Format 호출하기

이 문서는 영문 원고를 AI로 번역한 내용이라 표현이 어색할 수 있습니다.

자체 서비스에서 Format run을 시작합니다. 이 페이지는 invoke 계약만 다룹니다. receipt는 실행과 결과, 스키마는 구조화 출력, 키 보관·멱등성·웹훅·artifact 처리까지 포함한 파트너 연동 전체는 제품에 Format 임베드하기를 참고하세요.

정확한 요청·응답 스키마는 라이브 OpenAPI (https://api.sume.com/reference/json)에서 가져옵니다. 여기 표는 읽기 쉬운 요약이며, 두 번째 스키마가 아닙니다.

사전 요구 사항

모든 run 요청에는 다음이 필요합니다.

  1. Format의 statusactive입니다.
  2. Format의 api_trigger_enabledtrue입니다.
  3. API 키에 formats:readformats:write가 있습니다.
  4. 팀 워크스페이스가 소유한 Format이면, 키가 그 워크스페이스에서 발급된 것이어야 합니다.

한 번도 실행하지 않은 Format은 앞의 두 값이 inactive / false로 보이더라도 실행됩니다. 두 필드는 지연 프로비저닝되는 숨겨진 runner에서 읽히므로, GET /v1/formats/{id}는 첫 POST .../runs가 runner를 만들기 전까지 프로비저닝 전 상태를 보여 줍니다. 두 게이트가 run을 거절하는 것은 runner가 이미 존재하고 꺼져 있을 때뿐입니다. 값이 true가 될 때까지 폴링하며 연동을 막지 마세요 — Format을 호출하세요.

스코프

ScopeNeeded for
formats:readFormat 목록·읽기, run 읽기·목록입니다.
formats:writerun 생성, bulk-run 큐 생성, run 취소입니다.

Format API 호출 트리거가 출시되기 전에 만든 키에는 이 스코프가 없습니다. 이전 키는 모든 run 요청에서 403 insufficient_scope로 실패하며, 기존 키에 스코프를 추가할 수 없습니다. API Keys에서 새 키를 만들고 교체하세요 — 인증을 참고하세요.

서비스 계정 키로는 Format run을 만들 수 없습니다. 403 insufficient_scopedetails.reasonservice_account_format_runs_unsupported인 응답으로 실패합니다.

팀 Format에는 팀 키가 필요합니다

팀 워크스페이스가 소유한 Format은 그 워크스페이스에서 발급한 API 키로 호출합니다. 멤버십만으로는 부족합니다. 팀 멤버가 가진 개인 키는 403 workspace_key_required로 거절되며, details.workspace_id가 키가 나와야 하는 워크스페이스를 가리킵니다.

규칙은 돈을 따릅니다. 팀 Format의 run은 지갑에 청구되고, 팀의 generation concurrency에 잡히며, 팀 워크스페이스를 통해 다시 읽힙니다 — 생성 미디어를 structured output으로 바꾸는 harvest도 포함합니다. 개인 키를 쓰면 그 경계가 갈라집니다.

키는 개인 대시보드가 아니라 팀 대시보드에서 만드세요. 개인 Format에는 개인 키가 그대로 맞습니다.

멤버가 아닌 팀 handle은 404이며, 존재하지 않는 handle과 구분되지 않습니다 — 그래서 여기의 403은 항상 "맞는 팀, 틀린 키"를 뜻합니다.

그 워크스페이스에서 발급한 키는 formats:read / formats:write만 있으면 팀 vanity {handle}/{slug}를 쓸 수 있습니다. 만든 사람만 되는 것이 아니며, 404는 "작성자가 아니다"가 아닙니다. 팀 Format의 status / api_trigger_enabled워크스페이스 사실입니다. 한 번도 직접 호출하지 않은 멤버의 GET이 inactive / 트리거 꺼짐으로 보이지 않습니다.

호출하기

키의 워크스페이스가 소유한 Format을 handle과 slug로 호출합니다 — Agents Format 상세 페이지에 표시되는 주소와 같습니다. 팀 Format이면 handle이고, 그 org의 워크스페이스 키는 스코프만 있으면 POST할 수 있습니다.

Create a Format run

POST /v1/formats/{handle}/{slug}/runs

Required

수락된 run은 receipt와 함께 202를 반환합니다.

receipt의 format.id는 항상 불투명한 skl_… id입니다(run·빌링의 내부 SoT). 일상적인 호출에는 필요하지 않습니다.

GET /v1/formats/{handle}/{slug}GET /v1/formats/{handle}/{slug}/runs도 같은 방식으로 동작합니다.

Bulk run 큐

노트북에서 fan-out을 돌리지 않고 run 목록을 밤새 남겨 두는 계약은 대량 실행에 있습니다. POST …/bulk-runs(불투명 또는 vanity), concurrency 1–16, 최대 100 item, 그다음 GET /v1/format-run-queues/{queue_id}를 폴링합니다. 각 item은 여전히 Format run 하나이며, 큐는 두 번째 실행 엔진이 아닙니다.

불투명 URL(호환)

이미 경로를 저장한 클라이언트를 위해 불투명 경로는 계속 유효합니다.

요청 본문, 헤더, 스코프, 멱등성, spend cap, run receipt는 동일합니다 — vanity는 같은 Format으로 해석되어 같은 파이프라인을 실행합니다. 새 연동과 문서에서는 {handle}/{slug}를 선호하세요. 이름 변경이 저장된 URL을 깨뜨리면 안 될 때만 invoke_url을 유지하세요.

PublicFormat은 둘 다 노출합니다.

FieldMeaning
handle해석 가능한 현재 handle입니다. Formats by Sume에서는 sume입니다.
slugFormat의 URL 세그먼트입니다.
vanity_invoke_url{handle}/{slug} 경로이거나, 한쪽을 모를 때 null입니다. 이것을 선호하세요.
invoke_url불투명 경로입니다. 항상 존재하며, 항상 영구적입니다.

Formats by Sume는 sume handle에 있습니다. 소유자가 없어 계정 handle로는 주소를 잡을 수 없고, chase/sume-product-promo404 format_not_found를 반환합니다. 예약된 sume 네임스페이스가 그 주소이며, 모든 호출자에게 동일하고, 바로 호출할 수 있습니다:

run과 그 미디어, 그 지출은 호출한 키에 귀속됩니다 — 카탈로그 Format 자체는 소유자 없이 공유된 채로 남습니다. fork는 Format을 편집하고 싶을 때 여전히 쓸 수 있지만, 호출을 위한 선행 조건은 더 이상 아닙니다.

알 수 없는 handle, 알 수 없는 slug, 소유하지 않은 handle은 모두 같은 404 format_not_found를 반환합니다.

팀이 소유한 Format도 같은 vanity·불투명 호출 경로를 씁니다. 그 팀 워크스페이스에서 발급한 키로 인증하세요 — 팀 Format에는 팀 키가 필요합니다를 참고하세요.

요청 본문

FieldNotes
instruction작업 내용입니다. 최대 8000자. 선택 사항이며, 생략하면 Format 자체의 기본 instruction으로 실행합니다. Format 본문 뒤에 조합됩니다 — instruction 조합을 참고하세요.
input호출자 데이터의 JSON 객체입니다. run 워크스페이스의 파일로 기록되며, instruction이 아니라 데이터로만 다뤄집니다. 최대 64개 최상위 속성, 2097152 UTF-8 바이트(2 MiB)입니다. 형태는 직접 정합니다 — input — 호출자 데이터를 참고하세요.
on_active_run생략하면 Format run을 동시에 허용합니다(워크스페이스 generation concurrency는 그대로 적용). skip은 이미 진행 중인 run이 있으면 skipped run을 기록하고, reject409 format_run_in_progress를 반환합니다.
generation_spend_cap_usdrun당 상한입니다. Format 자체의 cap으로만 아래로 클램프되며, 올릴 수는 없습니다. Spend caps를 참고하세요.
output_schema / response_formatJSON Schema를 바인딩해 typed JSON으로 결과를 받습니다. 둘 다 보내면 400 invalid_request입니다. 전체 규칙: 구조화 출력.
primary_output_keyoutput에서 URL이 primary_output_url이 될 키입니다. 최대 64자입니다.
communication.webhook_url종료 receipt를 받을 공개 HTTPS 대상입니다. Run 웹훅을 참고하세요 — api.dev.sume.comapi.sume.com에서 수락·저장·전달됩니다.

— 호출자 데이터 (caller data)

input은 서비스가 run에 넘기는 JSON 객체입니다. 고정된 와이어 스키마가 아니며, Sume은 이 필드의 필드 목록을 공개하지 않습니다. 형태는 여러분이 정하고, Format 레시피는 자기가 아는 키만 읽습니다. 같은 Format을 호출하는 두 연동이 완전히 다른 객체를 보내도 둘 다 맞습니다.

이는 엄격한 계약인 output_schema와 정반대입니다. 둘을 확실히 구분하세요.

inputoutput_schema
방향여러분 → runrun → 여러분
형태백엔드에 편한 아무 JSON 객체지원 부분집합 안의 JSON Schema
검증 대상객체인지, 키 개수, 바이트 크기. 그게 전부입니다.부분집합의 모든 규칙
Sume이 예상하지 않은 형태그대로 실행됩니다. 모르는 키는 그냥 데이터입니다400 output_schema_invalid — 아무것도 실행되지 않고 청구되지 않습니다
도착지run 워크스페이스의 파일(/workspace/inputs/sume-action-input.json)run 이후의 projection

API가 검증하는 것

정확히 네 가지이고, 그 밖에는 없습니다.

검사규칙실패 시
타입JSON 객체여야 합니다. 배열·문자열·숫자는 거절됩니다. null과 생략은 모두 {}를 뜻합니다.400
속성 개수최상위 키 최대 64개. 그 안에 중첩된 키는 세지 않습니다.400
크기최대 2097152 UTF-8 바이트(2 MiB). 들여쓰기 없는 compact 직렬화 기준입니다.400
미디어 참조이미지·영상·오디오 파일을 가리키는 HTTPS URL은 객체 어느 깊이에 있든 run의 첨부 예산을 함께 씁니다. 합쳐서 30개, 그중 이미지 30개, 영상 10개, 오디오 10개까지입니다. Media referenced from input을 참고하세요.400

예약 키도, 필수 키도, 값 타입 규칙도, 이름 규칙도 없습니다. {"a": 1}과 40개 키짜리 중첩 주문 페이로드는 똑같이 유효합니다. 문서의 예시 input 객체를 필드 단위로 맞춰야 하는 와이어 계약으로 보지 마세요 — 어느 연동자에게 편했던 형태일 뿐, 스키마가 아닙니다.

64개는 최상위 키만 세므로 중첩은 공짜입니다. 잎 노드가 64개를 넘어도 묶어 두면 됩니다.

run이 실제로 받는 것

input은 두 칸 들여쓰기로 직렬화되어 run 워크스페이스의 고정 경로 /workspace/inputs/sume-action-input.json통째로 기록됩니다 — 크기와 무관하게 전부입니다. 프롬프트에는 JSON 자체가 실리지 않습니다. 파일 경로·크기·최상위 키 목록을 알리고, 행동하기 전에 그 파일을 읽으라고 지시하는, 크기가 제한된 포인터 블록만 실립니다.

Format 본문과 같은 attach-always / inline-never 원칙입니다. 페이로드는 에이전트의 Read 도구가 열 수 있는 디스크에 있고, 턴은 읽기 좋게 남습니다.

Format run의 전체 조합 순서는 이렇습니다.

Format 본문은 어떻게에 해당하므로 먼저 옵니다. instruction은 그 뒤라서 둘이 어긋나면 모델은 여러분이 요청한 쪽을 따릅니다. input은 마지막에, instruction이 가리킬 수 있는 데이터로 옵니다. instruction 조합을 참고하세요.

여기서 걸려 넘어지기 쉬운 동작이 둘 있습니다.

  • input은 블록도 파일도 만들지 않습니다. {}는 — 그리고 키가 모두 사라진 객체는 — [Sume action input] 섹션이 아예 없는 프롬프트를 만들며, 필드를 생략한 호출과 바이트 단위로 같습니다. input에서 product_url을 읽어라라고 적힌 Format 본문은 읽을 것이 없습니다.
  • 별도의 JSON 모드는 없습니다. instruction의 산문, input의 구조화 데이터, 또는 둘 다 모두 정상입니다. 레시피는 아는 키만 보고 나머지는 문맥으로 둡니다.

은 데이터이고, 절대 instruction이 아닙니다

포인터 블록의 문구는 신뢰 경계를 지키기 위해 있습니다. sume-action-input.json을 통해 들어온 내용은 호출자가 준 데이터이지 에이전트에게 내리는 명령이 아닙니다. 여러분이 쓰지 않은 내용 — 크롤링한 상품 설명, 고객 메시지, 공급사 필드 — 은 instruction에 이어 붙이지 말고 input에 넣으세요. 그래야 이 틀을 물려받습니다.

이것은 경계이지 샌드박스가 아닙니다. 자체 제품의 프롬프트 인젝션 대응과 같은 태도로 다루세요. 신뢰할 수 없는 텍스트를 instruction에 그대로 잇는 것보다 확실히 낫지만, 적대적인 페이로드를 그대로 통과시켜도 된다는 뜻은 아닙니다. run에는 spend cap이 있으므로 잘못된 input의 피해 범위는 Format의 cap으로 제한됩니다.

은 수락된 만큼 전달됩니다

input잘리지 않습니다. 2 MiB 수락 한도까지 객체 전체가 /workspace/inputs/sume-action-input.json에 기록되어 run에 디스크로 도착합니다. 프롬프트에는 포인터 블록만 실리며, 이 블록은 경로·바이트 수·앞 32개 최상위 키 이름으로 구성되어 태생적으로 작고 유한합니다. 예전에는 JSON을 프롬프트에 인라인하고 대략 앞 3860자에서 잘랐지만, 그 동작은 사라졌습니다. 라이브커머스 스크립트나 긴 상품 목록도 통째로 도착합니다.

instruction은 다릅니다. 프롬프트 텍스트라서 자기 [Format run instruction] 블록으로 실리고, 블록은 앞부분을 남기고 4000자에서 잘립니다.

Field수락전달
instruction8000자앞 ~4000자
inputcompact 기준 2097152 UTF-8 바이트전부 — 에이전트가 읽는 파일로

instruction은 4000자보다 넉넉히 안쪽에 두고, 데이터는 산문 대신 input에 넣으세요 — 파일에는 그런 예산이 없습니다.

Format 본문은 이 문제에서 완전히 벗어나 있습니다. 애초에 잘릴 턴 안에 없기 때문입니다. 턴에는 [Format attached: …] 포인터가 실리고 Agent가 그 파일을 여므로, 본문은 크기와 무관하게 문장 중간에서 잘린 조각이 아니라 통째로 도착합니다 — 여기에는 어떤 상한도 없습니다. Format을 저작한다면 Format 개요의 “SKILL.md 크기는 얼마여야 하나”를 참고하세요.

은 structured output까지 가지 않습니다

양쪽을 설계하기 전에 알아 둘 값입니다. output은 에이전트가 만들지 않습니다. run이 만든 미디어와 마지막 텍스트로부터 사후에 projection되며, 여러분의 input은 projection의 입력에 없습니다. 보낸 값 — 주문 id, SKU, 자체 로케일 — 은 run이 마무리 텍스트에서 스스로 되풀이하지 않는 한 output에 담길 수 없습니다.

그러니 output_schema로 자기 식별자를 돌려받으려 하지 마세요. 식별자는 여러분 쪽에 run.idIdempotency-Key로 키를 잡아 두고, output에는 run이 만든 것만 담으세요. 전체 동작은 파싱은 run 이후에 일어납니다에 있습니다.

멱등성

매 호출에 Idempotency-Key를 보내세요. 같은 본문으로 재전송하면 200과 원래 run이 돌아옵니다. 다른 본문 — 다른 instruction 포함 — 으로 재전송하면 409입니다.

Spend caps

모든 Format에는 generation spend cap이 있으며, run은 자신의 유효 cap을 넘길 수 없습니다. Format의 cap은 run이 따로 지정하지 않았을 때 물려받는 값입니다.

현재 값은 PublicFormat.generation_spend_cap_usd_micros에서 읽습니다. 항상 숫자입니다.

cap을 한 번도 지정하지 않은 Format은 플랫폼 기본값 $400을 쓰며, 출력 종류와 무관합니다.

Format을 등록할 때 generation_spend_cap_usd로 직접 설정하세요 — 0보다 크고 500 이하인 유한한 숫자입니다. null로 지우면 Format은 $400 기본값으로 돌아갑니다.

run 요청의 generation_spend_cap_usd는 플랫폼 최대치 $500까지 그 run만의 천장을 지정합니다. Format 자체의 cap보다 큰 값도 그대로 적용되며 아래로 클램프되지 않습니다 — 등록 당시보다 긴 프로덕션이라면 run 단위로 예산을 올릴 수 있습니다. 500을 넘으면 조용히 깎이는 대신 400입니다. 생략하면 run은 Format의 cap을 받습니다.

API 위 run은 unattended입니다

Format 본문은 대화형 채팅용으로 쓰이며, 사람을 기다리며 멈출 수 있습니다 — "비디오를 만들기 전에 이 미리보기 스틸을 승인하세요"는 Agents UI의 의도된 품질 게이트입니다.

API에는 물어볼 사람이 없습니다. 그래서 API run의 프롬프트에는 그 승인이 이미 허용됨이며 Format의 spend cap 안에서 유료 단계까지 계속해야 한다고 알려 줍니다. Scheduled run도 같습니다. 대화형 Agents UI만 여전히 멈추고 기다립니다.

정말로 끝낼 수 없는 run은 completed가 아니라 failed로 돌아옵니다.

status: "completed"를 실제 결과로 취급하세요. 중간에 멈춘 run을 대신 넘겨주지 않습니다.

401 vs 403 vs 404

HTTP 클래스가 첫 분기이고, error.code가 두 번째입니다. 키가 없으면 401 unauthorized입니다. 알려진 키에 formats:read / formats:write가 없으면 403 insufficient_scope이며, 절대 404 format_not_found가 아닙니다. 기존 키에 스코프를 덧붙일 수는 없습니다. API Keys에서 새 키를 만들고 교체하세요.

HTTPerror.codeWhenAuthority
401unauthorized키 없음, 잘못된 키, 자격 증명 두 개, 폐기됨, 알 수 없음. next_actionauthenticate.Official: RFC 9110 §15.5.2. Product SoT: OpenAPI 401.
403insufficient_scope유효한 키에 formats:read / formats:write가 없음. details.required_scope가 이름을 가리킴. next_actionauthenticate.Official: RFC 9110 §15.5.4; RFC 6750 insufficient_scope.
403insufficient_scopeFormat run 또는 패키지 쓰기의 서비스 계정 키 (details.reasonservice_account_format_runs_unsupported 또는 service_account_format_authoring_unsupported).Product SoT: 같은 코드, details.reason으로 구분. 새 403 코드를 만들지 않음.
403workspace_key_required팀 워크스페이스 멤버이지만 키가 그 워크스페이스에서 발급되지 않음. details.workspace_id가 가리킴.Product SoT. 멤버에게 팀 키를 만들라고 말하기 위해 404와 구분.
404format_not_found알 수 없음, 보관됨, 이 키의 워크스페이스 밖, 또는 멤버가 아닌 팀 handle. 맞는 handle 위의 멤버 팀 키는 이 404가 아님.Product SoT / #2393. 의도적 테넌시 숨김 — "다른 곳에 Format이 있다"거나 "작성자가 아니다"가 아님.
404format_run_not_found알 수 없는 run id이거나 다른 소유자의 run.Product SoT / #2393. 같은 숨김.
404format_run_queue_not_found알 수 없는 bulk-run 큐이거나 다른 소유자의 큐.Product SoT.
404previous_run_not_foundprevious_run_id를 모르거나 내 것이 아님.Product SoT. Format 주소는 유효했고 continuity id가 아니었음.
404format_content_not_found이 키에 Format은 있지만 그 패키지 경로는 없음.Product SoT.

오류

CodeStatusWhat to do
unauthorized401없거나, 잘못되었거나, 폐기되었거나, 알 수 없는 API 키. next_actionauthenticate.
insufficient_scope403키에 formats:read / formats:write가 없습니다. 이 기능 이전에 발급된 키에는 없습니다 — 새 키를 만드세요. next_actionauthenticate. format_not_found가 아닙니다.
workspace_key_required403Format이 팀 워크스페이스 소유인데 키가 그 워크스페이스에서 발급되지 않았습니다. details.workspace_id에서 만든 키를 쓰세요. next_actionauthenticate.
format_not_found404알 수 없거나, 보관되었거나, 이 키의 워크스페이스 밖이거나, 멤버가 아닌 팀 handle입니다. 맞는 {handle}/{slug} 위의 멤버 팀 키는 200이며 이 404가 아닙니다.
format_not_forkable409Format 카드가 아니라 내장 기능을 주소로 잡았습니다. Formats by Sume 또는 직접 만든 Format을 호출하세요.
format_api_trigger_disabled409이 Format의 API 호출 트리거가 꺼져 있습니다.
format_inactive409Format이 비활성입니다. API run을 받으려면 active로 설정하세요.
format_run_in_progress409on_active_run: "reject"이고 이미 진행 중인 run이 있습니다.
idempotency_conflict409Idempotency-Key가 다른 페이로드로 이미 사용되었습니다.
output_schema_invalid400output_schema가 지원 부분집합 밖입니다. details.violations[]가 각 문제를 가리킵니다 — 지원 스키마를 참고하세요.

다음