Session과 Turn
대화형으로 AI 직원을 부를 때는 Deployment를 고르고, Session을 만들고, Turn을 보냅니다. 한 Session은 하나의 Deployment에 고정되며 이전 대화가 이어집니다.
Deployment 조회
GET /v1/deployments는 이 키가 부를 수 있는 Deployment 목록을 돌려줍니다. (deployments:read)GET /v1/deployments/{deployment_id}는 이름, 버전, 상태(ACTIVE,RETIRED), 모델 등급(model_tier), 허용 도구, 선언된 결과 계약(outputs), 허용 입력 MIME 형식, 호출 속도 한도를 보여 줍니다.- 실제 모델 이름은 노출하지 않고 등급만 표시합니다.
Session 만들기
POST /v1/deployments/{deployment_id}/sessions는 Session과 첫 Turn을 한 번에 만듭니다. sessions:write와 turns:write가 필요하고 Idempotency-Key가 필수입니다.
- 서버는 접수 기록을 저장한 뒤에
202를 돌려줍니다. 연결이 끊겨도 접수된 Turn은 사라지지 않습니다. - 응답(receipt)에는
session_id,turn_id,status,idempotency_expires_at,status_url,events_url이 있고,Location헤더는 Turn 상세의 상대 주소입니다. - 이미 보낸 요청과 같은 키와 같은 본문이면 같은 receipt를 돌려줍니다. 같은 키에 다른 본문이면
409 IDEMPOTENCY_CONFLICT입니다. - receipt는 최소 24시간(
idempotency_expires_at), 그리고 해당 Turn이 끝나기 전까지 보존됩니다.
후속 Turn
POST /v1/sessions/{session_id}/turns로 같은 Session에 새 입력을 보냅니다.
- 같은 Session에는 한 번에 하나의 Turn만 실행됩니다. 앞선 Turn이 끝나기 전에 보내면
409 SESSION_BUSY입니다. 대기열은 없으니 종결을 확인한 뒤 보내세요. - 닫힌 Session에 보내면
409 SESSION_CLOSED입니다. - 서로 다른 Session은 병렬로 실행됩니다. 단, Project의 동시 실행 한도가 있습니다.
{
"error": {
"code": "SESSION_BUSY",
"message": "The session already has an active turn",
"retryable": false,
"request_id": "0b7b8f0e-0000-4000-8000-000000000004",
"details": {}
}
}조회, 취소, 닫기, 삭제
| 경로 | 설명 |
|---|---|
GET /v1/sessions/{session_id} | Session 상태(ACTIVE, CLOSED)와 진행 중 Turn |
GET /v1/sessions/{session_id}/turns | Turn 목록. after, limit 커서 |
GET /v1/sessions/{session_id}/turns/{turn_id} | Turn 상태, 사용량, 오류, 결과(outputs), next_cursor |
GET /v1/sessions/{session_id}/items | 공개 Item 기록 |
POST /v1/sessions/{session_id}/turns/{turn_id}/cancel | Turn 취소. 새 취소는 202, 이미 끝났으면 200 |
POST /v1/sessions/{session_id}/close | 유휴 Session을 닫음. 실행 중이면 409 |
DELETE /v1/sessions/{session_id} | 삭제 접수(202). 이후 내용 조회는 즉시 404 |
Turn 상태는 QUEUED, RUNNING, REQUIRES_ACTION, CANCEL_REQUESTED, SUCCEEDED, FAILED, CANCELED, EXPIRED입니다. SUCCEEDED, FAILED, CANCELED, EXPIRED가 종결 상태입니다. 실패한 Turn도 접수는 성공한 것이므로 실패 이유는 응답의 error.code로 확인합니다.
- 취소는 의도를 먼저 저장하며, 이미 끝난 외부 효과는 되돌리지 않습니다. 취소와 완료가 겹치면 먼저 끝난 쪽이 최종 상태가 됩니다.
- 삭제는 한도와 데이터의 삭제 설명을 보세요.
- 요청 헤더
X-Correlation-Id(영문, 숫자, 점, 밑줄, 콜론, 하이픈, 1~128자)를 붙이면 호출자 쪽 추적에 쓸 수 있습니다. 형식이 틀리면400 INVALID_CORRELATION_ID입니다.
입력 형식
{
"input": [
{"type": "TEXT", "text": "Compare the attached report with last month."},
{"type": "FILE", "file_id": "d3c1b8a0-0000-4000-8000-000000000003"}
],
"metadata": {"request_ref": "example-001"},
"limits": {"queue_seconds": 600, "execution_seconds": 3600, "max_su": 50}
}input은TEXT와FILE항목의 배열입니다. TEXT는 빈 문자열이나 공백만 있는 값이 안 됩니다. 여러 TEXT는 순서대로 줄바꿈을 넣어 실행합니다.FILE의file_id는 먼저POST /v1/files로 올려서 받은 값입니다. 한 번 어떤 Session이나 Run에 결속한 파일은 다른 실행에 다시 쓸 수 없으니 새로 올리세요.metadata는 최대 16개 키이며, 키는 1~64자, 문자열 값은 최대 512자입니다.limits는 선택입니다.queue_seconds는 1600,3600,execution_seconds는 1max_su는 0 초과 100 이하(소수 8자리까지)입니다. 상한을 넘으면 조용히 줄이지 않고422 LIMIT_OUT_OF_RANGE로 거절합니다.- 요청 JSON 본문은 UTF-8로 64KiB까지입니다. 넘으면
413 INPUT_TOO_LARGE입니다. 모델, 프롬프트, 도구 같은 선언되지 않은 필드는422 INVALID_INPUT입니다. - 파일은 개당 20MiB, 한 입력에 최대 20개입니다. 허용 MIME 형식은 Deployment마다 다릅니다.
출력 형식
Turn 상세의 outputs는 아래 네 가지 형식 중 하나씩입니다.
[
{"id": "o1", "key": "answer", "type": "TEXT", "visibility": "FINAL", "availability": "READY",
"item_id": "i1", "text": "Done."},
{"id": "o2", "key": "summary", "type": "JSON", "visibility": "FINAL", "availability": "READY",
"schema_ref": "summary", "data": {"count": 3}},
{"id": "o3", "key": "report", "type": "FILE", "visibility": "FINAL", "availability": "READY",
"artifact_id": "a1", "filename": "report.txt", "mime_type": "text/plain",
"size_bytes": 1024, "sha256": "..."},
{"id": "o4", "key": "reference", "type": "URL", "visibility": "FINAL", "availability": "READY",
"url": "https://example.com/report", "access": "UNKNOWN", "expires_at": null}
]| type | 내용 |
|---|---|
TEXT | 정화된 본문 text. 64KiB를 넘는 본문은 파일로 제공됩니다. |
JSON | 발행 시 정한 schema로 검증된 data. 크면 data 대신 artifact_id로 파일 제공 |
FILE | artifact_id, 파일 이름, MIME, 크기, sha256. Workflow와 Run의 다운로드 참고 |
URL | 외부 HTTPS 링크 url과 접근 방식(access). UpServe가 보관하거나 가용성을 보장하지 않습니다. |
visibility는INTERMEDIATE,PARTIAL,FINAL이며 최종 결과는FINAL입니다.availability가FAILED나EXPIRED인 항목은error가 함께 옵니다.- 결과 목록은 한 번에 최대 100개, 응답 256KiB까지이며
after와next_cursor로 이어 읽습니다. - 성공한 Turn은 발행 때
required로 정한 결과가 모두 있어야 합니다. 빠졌거나 형식이 틀리면 성공이 아니라 실패로 닫힙니다.
사용량
Turn과 Run 응답의 usage는 두 가지 상태입니다.
{"status": "PENDING", "total_su": null}FINAL이면total_su가 확정액입니다.PENDING이면 비용이 아직 정해지지 않은 것이고total_su는null입니다. 0 SU가 아닙니다. 나중에 같은 조회를 다시 하면 확정됩니다.GET /v1/usage는key_id,deployment_id,session_id,turn_id,run_id중 하나로 범위를 좁혀 확정액, 예약액, 항목별 내역을 보여 줍니다. (usage:read)- 같은 응답의
preparations는 조직 업무 만들기의 준비 비용을 따로 보여 줍니다. 모양은 위와 같은 상태·확정액·예약액·항목별 내역입니다. 준비가 진행 중이어도 실행 쪽status와total_su는 바뀌지 않습니다. 모든 Deployment를 허용받고works:read를 가진 키에서는 Project 전체 비용이 실행 합계에preparations합계를 더한 값입니다.- 키에
works:read가 있으면 Project의 모든 준비가, 없으면 그 키로 접수한 준비만 들어갑니다.key_id를 주면 그 키로 접수한 준비로 좁혀집니다. deployment_id,session_id,turn_id,run_id를 주면preparations는null입니다. 준비는 이들 어디에도 속하지 않기 때문입니다. 0 SU가 아닙니다.
- 키에
질문 해소 (RequiredAction)
AI 직원이 실행 중 호출자에게 질문해야 할 때 Turn이 REQUIRES_ACTION으로 멈추는 기능입니다. 현재 Private Beta에서는 제공하지 않습니다. 서비스 전체 설정이며 Project별로 켤 수 없습니다. 지금은 발행된 Deployment에 질문 도구가 들어가지 않고, 사람의 답이나 승인이 필요해진 워크플로 실행은 ACTION_REQUIRED_UNSUPPORTED로 끝납니다. 아래는 이 기능이 제공될 때의 계약입니다.
- 호출자가 답할 수 있는 질문(
CALLER)은POST /v1/sessions/{session_id}/actions/{action_id}/resolve로 답합니다.actions:resolve와Idempotency-Key가 필요합니다. - 워크플로 승인에는 별도의
actions:approve위임이 필요합니다. 고객 화면에서 사람이 결정하고 Run action API로 제출합니다. 워크플로 승인을 참고하세요. - 답변 기한이 지나면
409 ACTION_EXPIRED입니다.
curl -s -X POST "$BASE/v1/sessions/$SESSION_ID/actions/$ACTION_ID/resolve" \
-H "Authorization: Bearer $UPSERVE_API_KEY" \
-H "Idempotency-Key: answer-0001" \
-H "Content-Type: application/json" \
-d '{"answers":[{"question_id":"q1","text":"Use the Seoul office."}]}'