작업(Jobs)
**job(작업)**은 document(문서)를 수집(ingest)하고 embedding(임베딩)하거나 API task(작업)를 실행하는 등의 비동기 작업 단위입니다. /v1/jobs 엔드포인트(endpoint)를 사용해 organization(조직) 내 작업을 조회하고, 제어하고, 정리할 수 있습니다.
참고: 모든
/v1/jobs엔드포인트는Authorization: Bearer <token>헤더에 workspace API key(워크스페이스 API 키)가 필요합니다. 읽기 작업은 유효한 키를 허용하며, 쓰기 작업(cancel,reprocess,delete)은jobs:writescope(권한 범위)가 필요합니다.
Job 객체(작업)
섹션 제목: “Job 객체(작업)”| 필드 | 타입 | 설명 |
|---|---|---|
id | string | 고유한 작업 식별자입니다. |
org_id | string | 작업을 소유한 organization(조직)입니다. |
bucket_id | string | 작업이 속한 bucket(버킷)입니다. |
collection_id | string | null | 작업 대상 collection(컬렉션). (해당하는 경우) |
document_id | string | null | 연결된 수집 document(문서). (해당하는 경우) |
workflow_id | string | null | 연결된 workflow(워크플로우). (해당하는 경우) |
source_entry_id | string | null | 연결된 source entry(소스 항목). (해당하는 경우) |
priority | integer | priority(우선순위) 값이 낮을수록 먼저 실행됩니다(기본값 2). |
status | string | queued, extracting, chunking, embedding, indexing, ready, failed, cancelled 중 하나입니다. |
s3_key | string | 원본 파일 또는 artifact(아티팩트)의 저장소 키입니다. |
file_name | string | 원본 파일 이름입니다. |
file_size | integer | 파일 크기(바이트)입니다. |
file_type | string | null | 파일 타입입니다. 예: pdf, txt, embed_bulk. |
processing_type | string | null | source_connector, bucket_page_reindex 또는 다른 task type(작업 유형)입니다. |
estimated_cost | number | 큐에 넣을 때 예상 비용입니다. |
actual_cost | number | null | 완료 후 실제 비용입니다. |
chunks_count | integer | null | 생성된 chunk(청크) 개수입니다. (해당하는 경우) |
failed_phase | string | null | 상태가 failed일 때 실패한 phase(단계)입니다. |
error_category | string | null | 분류된 오류 원인입니다. |
error_message | string | null | 사람이 읽을 수 있는 오류 메시지입니다. |
retryable | boolean | null | 실패가 재시도 가능한지 여부입니다. |
retry_count | integer | 재시도 횟수입니다. |
reprocess_of_job_id | string | null | 이 작업이 재처리(reprocess) 재시도인 경우 원본 작업 ID입니다. |
worker_id | string | null | 현재 작업을 처리 중인 worker(워커)입니다. |
scheduled_at | string | null | 지연된 경우 ISO 8601 예약 시간입니다. |
started_at | string | null | ISO 8601 처리 시작 시간입니다. |
completed_at | string | null | ISO 8601 완료 시간입니다. |
created_at | string | ISO 8601 생성 시간입니다. |
updated_at | string | ISO 8601 마지막 업데이트 시간입니다. |
metadata_snapshot | object | null | audit(감사) 안전을 위해 원본 document(문서) metadata(메타데이터)의 스냅샷입니다. |
GET /v1/jobs/{job_id}
섹션 제목: “GET /v1/jobs/{job_id}”ID로 단일 작업을 조회합니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
job_id | string | Yes | Job(작업) 식별자입니다. |
응답 예시
섹션 제목: “응답 예시”{ "id": "job_01J8X...", "org_id": "org_abc123", "bucket_id": "bucket_legal", "collection_id": null, "document_id": "doc_01J8X...", "priority": 1, "status": "ready", "s3_key": "org_abc123/uploads/contract.pdf", "file_name": "contract.pdf", "file_size": 1048576, "file_type": "pdf", "estimated_cost": 0.05, "actual_cost": 0.047, "chunks_count": 42, "failed_phase": null, "error_category": null, "error_message": null, "retryable": null, "retry_count": 0, "reprocess_of_job_id": null, "worker_id": null, "scheduled_at": null, "started_at": "2026-06-19T04:12:00Z", "completed_at": "2026-06-19T04:12:08Z", "created_at": "2026-06-19T04:11:55Z", "updated_at": "2026-06-19T04:12:08Z", "metadata_snapshot": { "file_name": "contract.pdf", "source_path": "org_abc123/uploads/contract.pdf", "captured_at": "2026-06-19T04:11:55Z" }}| 상태 | 원인 |
|---|---|
404 | 작업을 찾을 수 없거나 해당 organization(조직)에 속하지 않습니다. |
GET /v1/jobs
섹션 제목: “GET /v1/jobs”organization(조직)의 작업을 최신순으로 조회합니다.
쿼리 매개변수
섹션 제목: “쿼리 매개변수”| 매개변수 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
bucket_id | string | No | — | 특정 bucket(버킷)으로 필터링합니다. |
status | string | No | — | 특정 status(상태)로 필터링합니다. |
limit | integer | No | 50 | 최대 결과 수입니다. 1~200 사이여야 합니다. |
응답 예시
섹션 제목: “응답 예시”[ { "id": "job_01J8X...", "org_id": "org_abc123", "bucket_id": "bucket_legal", "status": "ready", "file_name": "contract.pdf", "file_size": 1048576, "file_type": "pdf", "priority": 1, "created_at": "2026-06-19T04:11:55Z", "updated_at": "2026-06-19T04:12:08Z" }, { "id": "job_01J8Y...", "org_id": "org_abc123", "bucket_id": "bucket_hr", "status": "failed", "file_name": "handbook.docx", "file_size": 512000, "file_type": "docx", "priority": 2, "error_message": "Provider embedding timeout", "created_at": "2026-06-19T03:00:00Z", "updated_at": "2026-06-19T03:05:00Z" }]GET /v1/jobs/{job_id}/files
섹션 제목: “GET /v1/jobs/{job_id}/files”job(작업)과 연결된 파일을 조회합니다. Schift의 작업은 현재 단일 document(문서) 단위이므로 최대 하나의 파일을 반환합니다. 응답 형식은 OpenAI의 vector_store.file 객체와 동일합니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
job_id | string | Yes | Job(작업) 식별자입니다. |
응답 예시
섹션 제목: “응답 예시”{ "object": "list", "data": [ { "id": "doc_01J8X...", "object": "vector_store.file", "vector_store_id": "bucket_legal", "status": "uploaded", "filename": "contract.pdf", "created_at": "2026-06-19T04:11:55Z" } ], "has_more": false}| 상태 | 원인 |
|---|---|
404 | 작업을 찾을 수 없거나 해당 organization(조직)에 속하지 않습니다. |
GET /v1/jobs/{job_id}/download
섹션 제목: “GET /v1/jobs/{job_id}/download”job(작업)과 연결된 원본 파일을 다운로드합니다. 응답은 attachment(첨부) Content-Disposition 헤더와 함께 binary stream(바이너리 스트림)으로 반환됩니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
job_id | string | Yes | Job(작업) 식별자입니다. |
바이너리 파일 콘텐츠입니다. Content-Type은 작업의 file_type에서 가져오며, 기본값은 application/octet-stream입니다.
| 상태 | 원인 |
|---|---|
404 | 작업을 찾을 수 없거나, 작업에 파일이 없거나, 저장소에서 파일을 가져올 수 없습니다. |
POST /v1/jobs/{job_id}/cancel
섹션 제목: “POST /v1/jobs/{job_id}/cancel”queued(대기) 상태 또는 진행 중인 작업을 취소합니다.
참고: 이 엔드포인트는
jobs:writescope(권한 범위)가 필요합니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
job_id | string | Yes | Job(작업) 식별자입니다. |
쿼리 매개변수
섹션 제목: “쿼리 매개변수”| 매개변수 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
force | boolean | No | false | 작업이 진행 중이어도 강제로 취소(force-cancel)할지 여부입니다. |
- 작업이 이미 terminal state(종료 상태)(
ready,failed,cancelled)에 있으면, 응답은 현재 상태와 함께detail: "job already in terminal state"를 반환합니다. - 작업이 진행 중이고
force가false이면, 엔드포인트는400을 반환하고?force=true사용을 권장합니다. force=true이면 작업은 현재 진행 상태와 관계없이cancelled로 표시됩니다.
응답 예시
섹션 제목: “응답 예시”{ "status": "cancelled"}오류 예시
섹션 제목: “오류 예시”| 상태 | 원인 |
|---|---|
400 | 진행 중인 작업이면서 force=false인 경우입니다. |
404 | 작업을 찾을 수 없거나 해당 organization(조직)에 속하지 않습니다. |
409 | 작업이 더 이상 queued(대기) 상태가 아닙니다(경쟁 상태). |
POST /v1/jobs/{job_id}/reprocess
섹션 제목: “POST /v1/jobs/{job_id}/reprocess”실패했거나 다른 이유로 terminal state(종료 상태)인 작업을 다시 처리하는 새로운 작업을 생성합니다. 새 작업은 원본 source(소스), bucket(버킷), collection(컬렉션), priority(우선순위)를 복사하고 reprocess_of_job_id를 통해 원본과 연결됩니다.
참고: 이 엔드포인트는
jobs:writescope(권한 범위)가 필요합니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
job_id | string | Yes | Job(작업) 식별자입니다. |
응답 예시
섹션 제목: “응답 예시”{ "id": "job_01J8Z...", "org_id": "org_abc123", "bucket_id": "bucket_legal", "document_id": "doc_01J8X...", "status": "queued", "file_name": "contract.pdf", "file_size": 1048576, "priority": 1, "reprocess_of_job_id": "job_01J8X...", "created_at": "2026-06-19T05:00:00Z", "updated_at": "2026-06-19T05:00:00Z"}| 상태 | 원인 |
|---|---|
400 | 작업이 terminal state(종료 상태)가 아닙니다. |
404 | 작업을 찾을 수 없거나 해당 organization(조직)에 속하지 않습니다. |
DELETE /v1/jobs/{job_id}
섹션 제목: “DELETE /v1/jobs/{job_id}”작업을 삭제합니다. 진행 중인 작업은 삭제할 수 없습니다.
참고: 이 엔드포인트는
jobs:writescope(권한 범위)가 필요합니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 매개변수 | 타입 | 필수 | 설명 |
|---|---|---|---|
job_id | string | Yes | Job(작업) 식별자입니다. |
성공 시 204 No Content를 반환합니다.
| 상태 | 원인 |
|---|---|
400 | 진행 중인 작업은 삭제할 수 없습니다. |
404 | 작업을 찾을 수 없거나 해당 organization(조직)에 속하지 않습니다. |
POST /v1/admin/reap-stale-jobs
섹션 제목: “POST /v1/admin/reap-stale-jobs”오래 멈춰 있는 진행 중인 job(작업)을 failed로 표시합니다. 이 엔드포인트는 cron이나 platform administrator(플랫폼 관리자)가 죽은 worker(워커)로부터 복구하기 위해 사용됩니다.
참고: 이 엔드포인트는 일반적인 workspace API key(워크스페이스 API 키)를 사용하지 않습니다. 다음 중 하나를 허용합니다:
Authorization: Bearer <token>헤더에 포함된platform_adminJWT 또는 API key(API 키).- 서버의
CRON_SECRET환경 변수와 일치하는X-Cron-Secret헤더.
쿼리 매개변수
섹션 제목: “쿼리 매개변수”| 매개변수 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
timeout_minutes | integer | No | 30 | 작업이 얼마나 오래 멈춰 있어야 reap(정리)되는지(분). 범위는 1–1440입니다. |
요청 헤더
섹션 제목: “요청 헤더”| 헤더 | 필수 | 설명 |
|---|---|---|
X-Cron-Secret | Conditional | Cloud Scheduler / CLI 호출자를 위한 cron secret(크론 시크릿)입니다. |
Authorization | Conditional | UI 또는 수동 사용을 위한 Bearer <platform_admin_token>입니다. |
응답 예시
섹션 제목: “응답 예시”{ "timeout_minutes": 30, "reaped_count": 2, "jobs": [ { "job_id": "job_01J8X...", "org_id": "org_abc123", "stuck_status": "embedding" }, { "job_id": "job_01J8Y...", "org_id": "org_def456", "stuck_status": "extracting" } ]}| 상태 | 원인 |
|---|---|
401 | 유효한 인증이 제공되지 않았습니다. |
403 | X-Cron-Secret 헤더가 있지만 유효하지 않습니다. |