본문으로 건너뛰기
Sursa Developers

POST/v1/uploads/{upload_id}/complete

업로드 완료

complete_upload

모든 파트를 받으면 Sursa는 파일을 합치고, 파일 전체의 SHA-256을 본문의 sha256 값과 비교한 뒤, 단일 요청 업로드와 같은 검사(내용 시그니처에 따른 형식 확인과 바이러스 검사)를 실행해요. 결과는 ready이거나, reject_reason 값(checksum_mismatch, type_mismatch, unsupported_format, infected, scan_unavailable, unsafe_content)과 함께 rejected예요. 형식 검사나 바이러스 검사로 거부될 때마다 감사 로그에 file.rejected 항목이 기록돼요.

200 응답은 결과가 준비되었다는 뜻이고, 202 응답은 파일을 아직 검사하는 중이라는 뜻이에요(processing). 이때 결과는 GET /v1/uploads/{upload_id} 요청으로 받아요. 상태가 pending으로 돌아가면(API 인스턴스가 다시 시작되어 검사가 중단된 경우) complete 요청을 다시 보내세요. 결과가 나온 뒤 complete 요청을 반복하면 같은 결과를 반환해요. 빠진 파트가 있으면 409 uploads.incomplete 오류를 반환해요(details.missing). sha256 값이 생성할 때 선언한 값과 다르거나 parts[].etag 값이 받은 파트와 다르면 422 uploads.checksum_mismatch 오류를 반환해요. 준비가 끝났지만 쓰지 않은 업로드는 24시간 동안 유지돼요. 1.62.0에서 추가됐어요.

인증

Authorization 헤더로 API 키를 보내세요: Authorization: Bearer <키>.

경로 파라미터

  • upload_idstring필수

    업로드 ID(upl_ 뒤에 16진수 문자 32자).

    length ≤ 64

헤더 파라미터

  • Idempotency-Keystring

    쓰기 요청을 안전하게 재시도하기 위한 키예요. 출력 가능한 ASCII 문자 1~255자이며, 논리적 처리 단위마다 UUID v4를 하나씩 쓰기를 권장해요. 24시간 안에 같은 키로 재시도하면 처리를 다시 실행하지 않고, 저장된 응답(상태, 헤더, 본문)을 Idempotency-Replayed: true 헤더와 함께 반환해요. 같은 키를 다른 메서드, 경로, Content-Type 값이나 본문과 함께 보내면 409 api.idempotency_mismatch 오류를 반환하고, 첫 요청이 아직 실행 중이면 409 api.idempotency_in_progress 오류를 Retry-After: 1 헤더와 함께 반환해요. 5xx나 429 응답 뒤에는 키가 해제되어, 재시도하면 처리가 다시 실행돼요. 키의 적용 범위는 조직과 호출자(API 키, 사용자, 사용자 지정 소스 키)예요.

    length ≥ 1, length ≤ 255

요청 본문

application/json

객체: UploadComplete

  • sha256string필수

    전체 파일의 SHA-256.

  • partsarray of UploadPartRef

    선택적인 파트 확인: PUT …/parts/{n} 요청이 반환한 각 파트의 ETag.

    items ≤ 1000

응답

200결과가 준비되었어요: `ready` 또는 `rejected`.

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

  • Idempotency-Replayed

    true이면 이 Idempotency-Key 값으로 저장된 응답을 재생한 것이에요. 처리는 다시 실행되지 않았어요.

application/json

객체: Upload

  • idstring필수

    업로드 ID(upl_ 뒤에 16진수 32자).

  • purposeUploadPurpose필수
  • filenamestring필수

    파일 이름(폴더 제외).

  • content_typestring필수

    선언한 콘텐츠 유형. 선언하지 않았으면 비어 있어요.

  • sizeinteger (int64)필수

    파일 크기(바이트).

  • sha256string | null필수

    생성할 때나 complete 단계에서 선언한 파일의 SHA-256. 아직 모르면 null이에요.

  • statusUploadStatus필수
  • part_sizeinteger (int64)필수

    마지막 파트를 제외한 각 파트의 크기(5~100MiB).

  • part_countinteger필수

    파트 수.

    ≥ 1, ≤ 1000

  • parts_receivedinteger필수

    수신된 파트 수.

    ≥ 0

  • partsarray of UploadPart필수

    번호별로 수신된 파트(POST /v1/uploads 응답에서는 비어 있어요).

  • reject_reasonstring | null필수

    거부 사유(rejected): checksum_mismatch, type_mismatch, unsupported_format, infected, scan_unavailable, unsafe_content. 값이 늘어날 수 있는 열거형이에요. 거부되지 않았으면 null이에요.

  • reject_detailsobject | null필수

    거부 세부 정보(확장자, 선언한 형식과 감지한 형식, 체크섬). 거부되지 않았으면 null이에요.

  • created_atstring (date-time)필수

    업로드가 생성된 시각.

  • expires_atstring (date-time)필수

    업로드를 완료하고, 준비된 뒤에는 사용해야 하는 기한.

  • completed_atstring (date-time) | null필수

    검사가 끝난 시각(ready 또는 rejected).

  • consumed_atstring (date-time) | null필수

    업로드가 사용된 시각(카드, 압축 파일 또는 가져오기에서).

202파일을 아직 검사하는 중이에요(`processing`).

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

  • Idempotency-Replayed

    true이면 이 Idempotency-Key 값으로 저장된 응답을 재생한 것이에요. 처리는 다시 실행되지 않았어요.

application/json

객체: Upload

  • idstring필수

    업로드 ID(upl_ 뒤에 16진수 32자).

  • purposeUploadPurpose필수
  • filenamestring필수

    파일 이름(폴더 제외).

  • content_typestring필수

    선언한 콘텐츠 유형. 선언하지 않았으면 비어 있어요.

  • sizeinteger (int64)필수

    파일 크기(바이트).

  • sha256string | null필수

    생성할 때나 complete 단계에서 선언한 파일의 SHA-256. 아직 모르면 null이에요.

  • statusUploadStatus필수
  • part_sizeinteger (int64)필수

    마지막 파트를 제외한 각 파트의 크기(5~100MiB).

  • part_countinteger필수

    파트 수.

    ≥ 1, ≤ 1000

  • parts_receivedinteger필수

    수신된 파트 수.

    ≥ 0

  • partsarray of UploadPart필수

    번호별로 수신된 파트(POST /v1/uploads 응답에서는 비어 있어요).

  • reject_reasonstring | null필수

    거부 사유(rejected): checksum_mismatch, type_mismatch, unsupported_format, infected, scan_unavailable, unsafe_content. 값이 늘어날 수 있는 열거형이에요. 거부되지 않았으면 null이에요.

  • reject_detailsobject | null필수

    거부 세부 정보(확장자, 선언한 형식과 감지한 형식, 체크섬). 거부되지 않았으면 null이에요.

  • created_atstring (date-time)필수

    업로드가 생성된 시각.

  • expires_atstring (date-time)필수

    업로드를 완료하고, 준비된 뒤에는 사용해야 하는 기한.

  • completed_atstring (date-time) | null필수

    검사가 끝난 시각(ready 또는 rejected).

  • consumed_atstring (date-time) | null필수

    업로드가 사용된 시각(카드, 압축 파일 또는 가져오기에서).

401자격 증명(세션 쿠키나 API 키)을 보내지 않았거나 키를 찾을 수 없어요.

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

403이 동작은 허용되지 않아요. 역할이 부족하거나, 컬렉션이나 카드에 접근할 수 없거나, 요청이 “View as” 모드로 실행 중이거나, 조직이 정지 또는 삭제된 경우예요(`detail` 필드는 `code: org_suspended | org_deleted` 값을 가진 객체예요).

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

404객체가 없거나 접근할 수 없어요. API는 접근이 제한된 객체가 존재하는지 확인해 주지 않아요.

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

409객체의 상태 때문에 이 동작을 할 수 없어요. 예를 들어 중복이거나, 인덱싱 중이거나, 이미 처리된 작업인 경우예요.

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

410객체가 있었지만 더는 사용할 수 없어요. 링크를 이미 사용했거나 링크가 만료되었거나, 보존 기간이 끝나 파일이 삭제되었어요.

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

422유효성 검사 오류예요. 본문이나 파라미터가 스키마와 맞지 않거나(`detail` 필드는 유효성 검사 오류 목록), 파라미터 값이 허용 범위를 벗어났어요(`detail` 필드는 메시지).

응답 헤더

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

429요청이 너무 많거나(`api.rate_limited`), 조직의 분·일·월 할당량을 다 썼거나(`api.quota_exceeded`, `error.details` 필드에 `quota`, `limit`, `reset_at` 값이 있어요), 조직의 한도에 도달했거나, 답변 서비스가 바쁜 상태예요(`answers.engine_busy`). `Retry-After` 헤더에 적힌 시간만큼 기다리세요.

응답 헤더

  • Retry-After

    요청을 다시 시도하기 전에 기다릴 초.

  • RateLimit-Policy

    적용 중인 한도. IETF 초안 draft-ietf-httpapi-ratelimit-headers 형식이며, 쉼표로 구분한 "<name>";q=<quota>;w=<window in seconds> 항목으로 이루어져요. key 항목은 API 키의 요청 속도예요(할당량은 버스트, 시간 창은 버스트가 완전히 다시 채워지는 시간이에요. 세션에서는 user, 자격 증명이 없으면 ip예요). minute, day, month 항목은 UTC 기준 달력상의 분, 일, 월에 대한 조직의 할당량이에요.

  • RateLimit

    RateLimit-Policy 헤더의 각 한도에서 남은 양: "<name>";r=<remaining>;t=<seconds until reset>.

  • X-RateLimit-Limit

    RateLimit-Policy 헤더에서 가장 엄격한 항목(남은 요청 수가 가장 적은 항목)의 한도.

  • X-RateLimit-Remaining

    가장 엄격한 한도에서 남은 요청 수.

  • X-RateLimit-Reset

    가장 엄격한 한도가 초기화될 때까지 남은 초.

application/json

객체: Error

오류 코드

모든 요청에 공통으로 쓰이는 코드 외에 이 엔드포인트가 error.code로 반환할 수 있는 코드예요.

안전한 재시도

POST와 PATCH 요청마다 Idempotency-Key 헤더(예: UUID)를 보내세요. 24시간 안에 같은 키로 재시도하면 요청을 다시 실행하지 않고 저장된 응답을 반환해요.

호출 한도

응답에는 RateLimit, RateLimit-Policy 헤더와 이전 헤더인 X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset이 담겨요. 429 응답에는 초 단위의 Retry-After 헤더가 있어요. 그만큼 기다린 뒤 재시도하세요.

← uploads · API 레퍼런스