Base URL
http://localhost:8080/api/v1
Endpoints Summary
Shannon provides 40+ REST endpoints across 8 categories:
Task Operations (10 endpoints)
Endpoint Description POST /tasksSubmit a new task POST /tasks/streamSubmit task and receive stream URL GET /tasksList tasks with filters (limit, offset, status, session_id) GET /tasks/{id}Get task status and result GET /tasks/{id}/eventsGet persistent event history GET /tasks/{id}/timelineGet deterministic Temporal timeline POST /tasks/{id}/pausePause a running task at workflow checkpoints POST /tasks/{id}/resumeResume a previously paused task GET /tasks/{id}/control-stateGet pause/cancel control state for a task POST /tasks/{id}/cancelCancel a queued or running task
Streaming (2 endpoints)
Endpoint Description GET /stream/sse?workflow_id={id}Server-Sent Events streaming GET /stream/ws?workflow_id={id}WebSocket streaming
Session Management (6 endpoints)
Endpoint Description GET /sessionsList sessions with pagination GET /sessions/{sessionId}Get session details GET /sessions/{sessionId}/historyGet session conversation history GET /sessions/{sessionId}/eventsGet session events (grouped by turn) PATCH /sessions/{sessionId}Update session title (UUID or external_id) DELETE /sessions/{sessionId}Delete session (soft delete; 204 idempotent)
Schedules (8 endpoints)
Endpoint Description POST /schedulesCreate a new schedule GET /schedulesList schedules GET /schedules/{id}Get schedule details GET /schedules/{id}/runsGet schedule run history PUT /schedules/{id}Update schedule configuration POST /schedules/{id}/pausePause a schedule POST /schedules/{id}/resumeResume a schedule DELETE /schedules/{id}Delete a schedule
Authentication (8 endpoints)
Endpoint Description POST /auth/registerRegister a new user POST /auth/loginLogin and obtain tokens POST /auth/refreshRefresh access token GET /auth/meGet current user info POST /auth/api-keys/refreshRefresh an API key GET /auth/api-keysList API keys POST /auth/api-keysCreate a new API key DELETE /auth/api-keys/{id}Revoke an API key
Approvals & HITL Review (3 endpoints)
Endpoint Description POST /approvals/decisionSubmit a human approval decision GET /tasks/{id}/reviewGet HITL review details POST /tasks/{id}/reviewSubmit HITL review decision
OpenAI Compatible (3 endpoints)
Endpoint Description POST /v1/chat/completionsChat completions (streaming supported) GET /v1/modelsList available models GET /v1/models/{model}Get model details
Health & Observability (3 endpoints)
Endpoint Auth Required Description GET /healthNo Health check probe GET /readinessNo Readiness probe (checks orchestrator) GET /openapi.jsonNo OpenAPI 3.0 specification
Authentication
Development : Authentication is disabled by default (GATEWAY_SKIP_AUTH=1).Production : Set GATEWAY_SKIP_AUTH=0 and use API keys.
curl -H "X-API-Key: sk_test_123456" \
http://localhost:8080/api/v1/tasks
SSE Streaming Authentication
Browser EventSource cannot send custom headers. In production, proxy SSE via your backend and inject X-API-Key or Bearer headers. For SSE endpoints, the api_key query parameter is supported as a fallback (e.g., ?api_key=sk_...).
const eventSource = new EventSource (
`/api/v1/stream/sse?workflow_id= ${ id } `
);
Header Required Description X-API-KeyYes* API authentication key Content-TypeYes (POST) application/jsonIdempotency-KeyNo Prevents duplicate submissions (24h cache) traceparentNo W3C trace context for distributed tracing
*Not required if GATEWAY_SKIP_AUTH=1
Header Description X-Workflow-IDTemporal workflow identifier for tracking X-Session-IDSession identifier X-RateLimit-LimitRequests allowed per minute X-RateLimit-RemainingRequests remaining in current window X-RateLimit-ResetUnix timestamp when limit resets
Rate Limiting
Default : 60 requests/minute per API key
Status : 429 Too Many Requests when exceeded
Header : Retry-After indicates seconds to wait
{
"error" : "Rate limit exceeded" ,
"retry_after" : 60
}
Idempotency
Prevent duplicate task submissions using Idempotency-Key header:
curl -X POST http://localhost:8080/api/v1/tasks \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-H "Content-Type: application/json" \
-d '{"query": "Analyze data"}'
Behavior :
Same key within 24 hours returns cached response
Request body is ignored for duplicate keys
Uses Redis for distributed cache
Error Handling
HTTP Status Codes
Code Meaning Common Causes 200Success Request completed 200OK Task submitted successfully 400Bad Request Invalid JSON, missing required fields 401Unauthorized Missing or invalid API key 404Not Found Task/session not found 429Too Many Requests Rate limit exceeded 500Internal Server Error Server error 502Bad Gateway Orchestrator unavailable 503Service Unavailable System overloaded
{
"error" : "Task not found"
}
CORS
CORS is enabled for development:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-API-Key, Idempotency-Key, traceparent
Production : Configure Access-Control-Allow-Origin to specific domains.
Timeouts
Operation Timeout HTTP Read 30 seconds HTTP Write 30 seconds HTTP Idle 60 seconds Agent Execution 10 minutes (configurable via AGENT_TIMEOUT_SECONDS)
Best Practices
1. Always Use Idempotency Keys
import uuid
import requests
response = requests.post(
"http://localhost:8080/api/v1/tasks" ,
headers ={
"X-API-Key" : "sk_test_123456" ,
"Idempotency-Key" : str (uuid.uuid4())
},
json ={ "query" : "Analyze data" }
)
2. Implement Exponential Backoff
import time
def submit_with_retry ( query , max_retries = 3 ):
for attempt in range (max_retries):
response = requests.post(url, json ={ "query" : query})
if response.status_code == 429 :
retry_after = int (response.headers.get( "Retry-After" , 60 ))
time.sleep(retry_after)
continue
return response
3. Stream Events for Long Tasks
import httpx
with httpx.stream(
"GET" ,
f "http://localhost:8080/api/v1/stream/sse?workflow_id= { task_id } " ,
headers ={ "X-API-Key" : "sk_test_123456" }
) as response:
for line in response.iter_lines():
if line.startswith( "data:" ):
event = json.loads(line[ 5 :])
print (event[ "type" ])
response = requests.post(
"http://localhost:8080/api/v1/tasks" ,
headers ={ "X-API-Key" : "sk_test_123456" },
json ={ "query" : "Analyze data" }
)
workflow_id = response.headers.get( "X-Workflow-ID" )
# Use workflow_id for streaming or Temporal UI
Quick Example
#!/bin/bash
API_KEY = "sk_test_123456"
BASE = "http://localhost:8080/api/v1"
# Submit task
RESPONSE =$( curl -s -X POST " $BASE /tasks" \
-H "X-API-Key: $API_KEY " \
-H "Content-Type: application/json" \
-d '{"query": "What is 2+2?"}' )
TASK_ID =$( echo $RESPONSE | jq -r '.task_id' )
echo "Task: $TASK_ID "
# Get status
curl -s " $BASE /tasks/ $TASK_ID " -H "X-API-Key: $API_KEY " | jq
# Stream events
curl -N " $BASE /stream/sse?workflow_id= $TASK_ID " -H "X-API-Key: $API_KEY "
Next Steps
Submit Tasks Task submission endpoint
Streaming SSE and WebSocket streaming
Sessions Session management
Python SDK Use the Python SDK