워크플로우
워크플로우(workflow) API를 사용하면 블록(block)과 엣지(edge)로 구성된 결정적인 DAG(방향성 비순환 그래프) 기반 파이프라인(pipeline)을 만들 수 있습니다. 빈 그래프(graph)나 내장 템플릿(template)으로 시작해 워크플로우를 프로그래밍 방식으로 생성하고, 동기 또는 비동기로 실행(run)하며, 실행과 로그를 조회하고, 워크플로우 정의를 YAML로 임포트(import)하거나 익스포트(export)할 수 있습니다.
모든 워크플로우 라우트는 API 키로 인증되며, 해당 키를 소유한 조직(organization) 범위에서 동작합니다.
참고: 대시보드 사용자는
/v1/organizations/\{org_id\}/workflows라는 조직(organization) 범위 라우트를 통해 워크플로우를 관리할 수도 있습니다. 아래 라우트는 공개 API 키 인터페이스입니다.
모든 요청에 Bearer API 키가 포함되어야 합니다:
curl -H "Authorization: Bearer $SCHIFT_API_KEY" \ https://api.schift.io/v1/workflows기본 URL
섹션 제목: “기본 URL”모든 워크플로우 엔드포인트는 다음 경로에 호스팅됩니다:
https://api.schift.io/v1/workflows워크플로우 모델
섹션 제목: “워크플로우 모델”워크플로우(workflow)는 블록(block)과 엣지(edge)로 구성된 DAG(방향성 비순환 그래프)입니다.
| 항목 | 타입 | 설명 |
|---|---|---|
id | string | 워크플로우 식별자. |
name | string | 사람이 읽기 쉬운 이름. |
description | string | 선택적 설명. |
status | string | draft, published, 또는 archived. |
graph.nodes | array | 워크플로우 내 블록 목록. |
graph.edges | array | 블록 간 연결. |
created_at | string | ISO 8601 타임스탬프. |
updated_at | string | ISO 8601 타임스탬프. |
POST /v1/workflows
섹션 제목: “POST /v1/workflows”새로운 워크플로우(workflow)를 생성합니다. 빈 그래프(graph)에서 시작하거나 내장 템플릿(template)에서 시작할 수 있습니다.
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
name | string | 예 | 워크플로우 이름. |
description | string | 아니오 | 선택적 설명. |
template | string | 아니오 | 내장 템플릿(template) ID 중 하나입니다. graph와 함께 사용할 수 없습니다. |
graph | object | 아니오 | nodes와 edges로 구성된 초기 DAG입니다. |
내장 템플릿(template): basic_rag, document_qa, conversational_rag, multi_source_rag, agentic_rag, image_ocr_ingest, chat_rag, chatroom_memory_search.
예시 요청
섹션 제목: “예시 요청”curl -X POST https://api.schift.io/v1/workflows \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Document QA", "description": "Upload, parse, chunk, embed, and store documents.", "template": "document_qa" }'예시 응답
섹션 제목: “예시 응답”{ "id": "wf_abc123def456", "name": "Document QA", "description": "Upload, parse, chunk, embed, and store documents.", "status": "draft", "graph": { "nodes": [ { "id": "start_001", "type": "start", "title": "Start", "position": {"x": 100, "y": 100}, "config": {} } ], "edges": [] }, "created_at": "2026-06-19T05:00:00+00:00", "updated_at": "2026-06-19T05:00:00+00:00"}에러 예시
섹션 제목: “에러 예시”// 400{ "detail": "Code blocks are disabled in hosted workflows"}GET /v1/workflows
섹션 제목: “GET /v1/workflows”인증된 조직(organization)의 모든 워크플로우(workflow)를 조회합니다.
예시 응답
섹션 제목: “예시 응답”[ { "id": "wf_abc123def456", "name": "Document QA", "description": "Upload, parse, chunk, embed, and store documents.", "status": "draft", "block_count": 1, "updated_at": "2026-06-19T05:00:00+00:00" }]GET /v1/workflows/{workflow_id}
섹션 제목: “GET /v1/workflows/{workflow_id}”전체 그래프(graph)를 포함한 단일 워크플로우(workflow) 정의를 조회합니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 이름 | 타입 | 설명 |
|---|---|---|
workflow_id | string | 워크플로우 식별자. |
에러 예시
섹션 제목: “에러 예시”// 404{ "detail": "Workflow not found"}PATCH /v1/workflows/{workflow_id}
섹션 제목: “PATCH /v1/workflows/{workflow_id}”워크플로우(workflow)의 메타데이터 또는 그래프(graph)를 업데이트합니다. 그래프를 변경하면 검증(validate)이 실행됩니다.
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
name | string | 아니오 | 새로운 워크플로우 이름. |
description | string | 아니오 | 새로운 설명. |
status | string | 아니오 | draft, published, 또는 archived. |
graph | object | 아니오 | nodes와 edges로 구성된 대체 DAG입니다. |
참고: 워크플로우(workflow)를 실행(run)하려면
published상태여야 합니다.
에러 예시
섹션 제목: “에러 예시”// 400 invalid_graph{ "error": "invalid_graph", "errors": ["Missing required input on block chunk_001"]}// 400{ "detail": "Code blocks are disabled in hosted workflows"}DELETE /v1/workflows/{workflow_id}
섹션 제목: “DELETE /v1/workflows/{workflow_id}”워크플로우(workflow)와 그 정의를 삭제합니다. 성공 시 204 No Content를 반환합니다.
에러 예시
섹션 제목: “에러 예시”// 404{ "detail": "Workflow not found"}POST /v1/workflows/{workflow_id}/blocks
섹션 제목: “POST /v1/workflows/{workflow_id}/blocks”기존 워크플로우(workflow)에 블록(block)을 추가합니다.
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
type | string | 예 | 블록(block) 타입입니다. GET /v1/workflows/meta/block-types를 참조하세요. |
title | string | 아니오 | 표시 제목입니다. 지정하지 않으면 블록 타입 라벨이 사용됩니다. |
position | object | 아니오 | {"x": number, "y": number}. 기본값은 {"x": 0, "y": 0}입니다. |
config | object | 아니오 | 블록(block)별 설정입니다. |
예시 요청
섹션 제목: “예시 요청”curl -X POST https://api.schift.io/v1/workflows/wf_abc123def456/blocks \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "llm", "title": "Answer generator", "position": {"x": 400, "y": 200}, "config": { "model": "gemini-2.5-flash-lite", "temperature": 0.7, "max_tokens": 1024 } }'예시 응답
섹션 제목: “예시 응답”{ "id": "llm_7a8b9c0d", "type": "llm", "title": "Answer generator", "config": { "model": "gemini-2.5-flash-lite", "temperature": 0.7, "max_tokens": 1024 }, "position": {"x": 400, "y": 200}}에러 예시
섹션 제목: “에러 예시”// 400{ "detail": "Code blocks are disabled in hosted workflows"}DELETE /v1/workflows/{workflow_id}/blocks/{block_id}
섹션 제목: “DELETE /v1/workflows/{workflow_id}/blocks/{block_id}”워크플로우(workflow)에서 블록(block)을 제거합니다. 연결된 엣지(edge)는 자동으로 제거됩니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 이름 | 타입 | 설명 |
|---|---|---|
workflow_id | string | 워크플로우 식별자. |
block_id | string | 블록 식별자. |
성공 시 204 No Content를 반환합니다.
POST /v1/workflows/{workflow_id}/edges
섹션 제목: “POST /v1/workflows/{workflow_id}/edges”두 블록(block) 사이에 엣지(edge)를 추가합니다.
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
source | string | 예 | 소스 블록 ID. |
target | string | 예 | 타겟 블록 ID. |
source_handle | string | 아니오 | 출력 포트(port)입니다. 기본값은 output입니다. |
target_handle | string | 아니오 | 입력 포트(port)입니다. 기본값은 input입니다. |
예시 요청
섹션 제목: “예시 요청”curl -X POST https://api.schift.io/v1/workflows/wf_abc123def456/edges \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "source": "retriever_001", "target": "llm_7a8b9c0d", "source_handle": "results", "target_handle": "vars" }'예시 응답
섹션 제목: “예시 응답”{ "id": "edge_a1b2c3d4", "source": "retriever_001", "target": "llm_7a8b9c0d", "source_handle": "results", "target_handle": "vars"}에러 예시
섹션 제목: “에러 예시”// 400{ "detail": "Source block not found: retriever_001"}DELETE /v1/workflows/{workflow_id}/edges/{edge_id}
섹션 제목: “DELETE /v1/workflows/{workflow_id}/edges/{edge_id}”워크플로우(workflow)에서 엣지(edge)를 제거합니다. 성공 시 204 No Content를 반환합니다.
POST /v1/workflows/{workflow_id}/run
섹션 제목: “POST /v1/workflows/{workflow_id}/run”워크플로우(workflow)를 실행(run)합니다.
쿼리 매개변수
섹션 제목: “쿼리 매개변수”| 이름 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
mode | string | 아니오 | async(기본값) 또는 sync. |
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
inputs | object | 아니오 | 워크플로우(workflow)에 전달되는 키-값 입력값입니다. |
비동기 실행(기본값)
섹션 제목: “비동기 실행(기본값)”비동기 실행(run)은 백그라운드 작업으로 큐에 들어갑니다. 응답에 포함된 실행 ID로 GET /v1/workflows/\{workflow_id\}/runs/\{run_id\}를 폴(poll)하여 조회할 수 있습니다.
예시 요청
섹션 제목: “예시 요청”curl -X POST "https://api.schift.io/v1/workflows/wf_abc123def456/run?mode=async" \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "inputs": {"query": "What is vector search?"} }'예시 응답
섹션 제목: “예시 응답”{ "id": "run_9f8e7d6c", "workflow_id": "wf_abc123def456", "status": "pending"}동기 실행
섹션 제목: “동기 실행”동기 실행(run)은 워크플로우(workflow)가 끝날 때까지 기다린 뒤 최종 실행 상태를 반환합니다.
예시 요청
섹션 제목: “예시 요청”curl -X POST "https://api.schift.io/v1/workflows/wf_abc123def456/run?mode=sync" \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "inputs": {"query": "What is vector search?"} }'예시 응답
섹션 제목: “예시 응답”{ "id": "run_9f8e7d6c", "workflow_id": "wf_abc123def456", "status": "completed", "inputs": {"query": "What is vector search?"}, "outputs": {"answer": "Vector search finds similar vectors in a database."}, "block_states": { "llm_7a8b9c0d": { "block_id": "llm_7a8b9c0d", "status": "completed", "inputs": {"vars": {"query": "What is vector search?"}}, "outputs": {"response": "Vector search finds similar vectors in a database."}, "error": null, "started_at": "2026-06-19T05:05:00+00:00", "finished_at": "2026-06-19T05:05:01+00:00", "duration_ms": 1200 } }, "error": null, "started_at": "2026-06-19T05:05:00+00:00", "finished_at": "2026-06-19T05:05:02+00:00"}에러 예시
섹션 제목: “에러 예시”// 409 workflow_not_published{ "error": "workflow_not_published", "message": "Publish workflow before running", "status": "draft"}// 403{ "detail": "Upgrade your plan to continue"}// 402{ "allowed": false, "reason": "quota_exceeded"}// 400{ "detail": "Workflow exceeds maximum of 100 blocks (has 120)"}POST /v1/workflows/{workflow_id}/webhook/{path}
섹션 제목: “POST /v1/workflows/{workflow_id}/webhook/{path}”수신된 웹훅(webhook)으로 워크플로우(workflow) 실행(run)을 트리거합니다. 요청 본문, 헤더, 쿼리 매개변수, 메서드, 경로가 워크플로우의 입력값으로 전달됩니다.
경로 매개변수
섹션 제목: “경로 매개변수”| 이름 | 타입 | 설명 |
|---|---|---|
workflow_id | string | 워크플로우 식별자. |
path | string | 나머지 웹훅(webhook) 경로. |
예시 요청
섹션 제목: “예시 요청”curl -X POST https://api.schift.io/v1/workflows/wf_abc123def456/webhook/incoming \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"event": "document.uploaded"}'예시 응답
섹션 제목: “예시 응답”{ "id": "run_a1b2c3d4", "workflow_id": "wf_abc123def456", "status": "pending"}에러 예시
섹션 제목: “에러 예시”// 413{ "detail": "Workflow webhook body exceeds 1MB cap"}// 400{ "detail": "Invalid JSON body: Expecting value"}GET /v1/workflows/{workflow_id}/runs
섹션 제목: “GET /v1/workflows/{workflow_id}/runs”워크플로우(workflow)의 실행(run) 목록을 조회합니다.
예시 응답
섹션 제목: “예시 응답”[ { "id": "run_9f8e7d6c", "workflow_id": "wf_abc123def456", "status": "completed", "inputs": {"query": "What is vector search?"}, "outputs": {"answer": "Vector search finds similar vectors in a database."}, "started_at": "2026-06-19T05:05:00+00:00", "finished_at": "2026-06-19T05:05:02+00:00" }]GET /v1/workflows/{workflow_id}/runs/{run_id}
섹션 제목: “GET /v1/workflows/{workflow_id}/runs/{run_id}”블록(block) 수준 상태를 포함한 단일 실행(run)을 조회합니다.
에러 예시
섹션 제목: “에러 예시”// 404{ "detail": "Workflow run not found"}GET /v1/workflows/{workflow_id}/runs/{run_id}/logs
섹션 제목: “GET /v1/workflows/{workflow_id}/runs/{run_id}/logs”실행(run)의 실행 로그를 폴(poll) 형태로 조회합니다.
쿼리 매개변수
섹션 제목: “쿼리 매개변수”| 이름 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
after_seq | integer | 아니오 | 이 시퀀스 번호 이후의 로그를 반환합니다. 기본값은 0입니다. |
예시 응답
섹션 제목: “예시 응답”{ "run_id": "run_9f8e7d6c", "status": "completed", "logs": [ {"seq": 1, "level": "info", "message": "Run started", "timestamp": "2026-06-19T05:05:00+00:00"}, {"seq": 2, "level": "info", "message": "Block llm_7a8b9c0d completed", "timestamp": "2026-06-19T05:05:01+00:00"} ]}POST /v1/workflows/{workflow_id}/validate
섹션 제목: “POST /v1/workflows/{workflow_id}/validate”워크플로우(workflow) 그래프(graph)를 수정하지 않고 검증(validate)합니다.
예시 응답
섹션 제목: “예시 응답”{ "valid": true, "errors": []}에러 예시
섹션 제목: “에러 예시”{ "valid": false, "errors": ["Block llm_7a8b9c0d has unconnected required input"]}POST /v1/workflows/import
섹션 제목: “POST /v1/workflows/import”YAML에서 워크플로우(workflow)를 임포트(import)합니다.
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
yaml | string | 예 | YAML 워크플로우 정의. |
YAML에는 version: 1, name, 그리고 최소한 하나의 블록(block)이 포함되어야 합니다. code 블록은 임포트(import) 시 거부됩니다.
예시 요청
섹션 제목: “예시 요청”curl -X POST https://api.schift.io/v1/workflows/import \ -H "Authorization: Bearer $SCHIFT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "yaml": "version: 1\nname: Simple RAG\nblocks:\n - id: start\n type: start\nedges: []" }'예시 응답
섹션 제목: “예시 응답”{ "id": "wf_imported123", "name": "Simple RAG", "status": "draft", "graph": { "nodes": [{"id": "start", "type": "start", "title": "Start", "position": {"x": 0, "y": 0}, "config": {}}], "edges": [] }, "created_at": "2026-06-19T05:10:00+00:00", "updated_at": "2026-06-19T05:10:00+00:00"}에러 예시
섹션 제목: “에러 예시”// 400{ "detail": "Missing required field: 'version'"}// 400{ "detail": "Code blocks are disabled in hosted workflows"}GET /v1/workflows/{workflow_id}/export
섹션 제목: “GET /v1/workflows/{workflow_id}/export”워크플로우(workflow) 정의를 YAML 또는 JSON으로 익스포트(export)합니다.
쿼리 매개변수
섹션 제목: “쿼리 매개변수”| 이름 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
format | string | 아니오 | yaml(기본값) 또는 json. |
yaml 형식의 응답은 text/yaml입니다. json 형식의 응답은 JSON입니다.
POST /v1/workflows/generate
섹션 제목: “POST /v1/workflows/generate”자연어(natural language) 프롬프트로 워크플로우(workflow)를 생성합니다. 이 기능은 프리미엄 기능입니다.
요청 본문
섹션 제목: “요청 본문”| 매개변수 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
prompt | string | 예 | 생성할 워크플로우에 대한 설명. |
model | string | 아니오 | 사용할 모델입니다. 기본값은 gemini-2.5-flash-lite입니다. |
에러 예시
섹션 제목: “에러 예시”// 403{ "error": "upgrade_required", "message": "Agentic workflow generation is a premium feature. Upgrade your plan to use it."}// 502{ "error": "upstream_error", "message": "Workflow execution failed"}GET /v1/workflows/meta/block-types
섹션 제목: “GET /v1/workflows/meta/block-types”사용 가능한 모든 블록 타입(block type), 카테고리(category), 입력/출력 포트(port), 기본 설정을 조회합니다.
GET /v1/workflows/meta/descriptors
섹션 제목: “GET /v1/workflows/meta/descriptors”노드(node) 디스크립터(descriptor)를 조회합니다. 카테고리(category)나 검색어로 필터링할 수 있습니다.
쿼리 매개변수
섹션 제목: “쿼리 매개변수”| 이름 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
category | string | 아니오 | 블록 카테고리(category)로 필터링합니다. |
q | string | 아니오 | 검색어. |
GET /v1/workflows/meta/descriptors/grouped
섹션 제목: “GET /v1/workflows/meta/descriptors/grouped”카테고리(category)별로 그룹화된 노드 디스크립터(descriptor)를 조회합니다.
GET /v1/workflows/meta/descriptors/{block_type}
섹션 제목: “GET /v1/workflows/meta/descriptors/{block_type}”단일 블록 타입(block type)의 디스크립터(descriptor)를 조회합니다.
에러 예시
섹션 제목: “에러 예시”// 404{ "detail": "No descriptor for block type 'unknown_block'"}GET /v1/workflows/meta/templates
섹션 제목: “GET /v1/workflows/meta/templates”내장 워크플로우 템플릿(template)을 조회합니다.
예시 응답
섹션 제목: “예시 응답”[ {"id": "basic_rag", "label": "Basic Rag"}, {"id": "document_qa", "label": "Document Qa"}, {"id": "conversational_rag", "label": "Conversational Rag"}]| 제한 | 값 | 비고 |
|---|---|---|
| 워크플로우당 블록 수 | 100 | 하드 제한. |
| 워크플로우당 엣지 수 | 200 | 하드 제한(블록 제한의 2배). |
| 웹훅(webhook) 본문 크기 | 1 MB | HTTP 413으로 거부됩니다. |
| 동기 실행(run) 제한 시간 | 60 s | 전체 워크플로우 제한 시간. |
| 블록(block)당 제한 시간 | 30 s | 개별 블록 제한 시간. |
| 실행 컨텍스트 크기 | 10 MB | 전체 변수 및 출력값. |
| 하위 워크플로우(subworkflow) 깊이 | 5 | 최대 중첩 하위 워크플로우 호출 수. |
기본 실행 사용량 상한:
| 사용량 상한 | 값 |
|---|---|
external_calls_total | 60 |
llm_calls | 20 |
web_search_calls | 10 |
실행 상태
섹션 제목: “실행 상태”실행(run)은 다음 상태 중 하나일 수 있습니다:
| 상태 | 설명 |
|---|---|
pending | 큐에 들어갔지만 시작되지 않음. |
running | 현재 실행 중. |
completed | 성공적으로 완료. |
failed | 에러로 인해 중단. |
cancelled | 완료 전 취소됨. |
API 버전
섹션 제목: “API 버전”| 버전 | 상태 | 비고 |
|---|---|---|
v1 | 현재 | 여기에 문서화된 모든 /v1/workflows/* 라우트가 현재 공개 인터페이스입니다. |
현재 v2 워크플로우 API는 없습니다. 새로운 연동은 /v1/workflows/* 라우트를 사용해야 합니다.