3. APIs
Base path: none (routes are mounted at root). Default port 5000
(run_server() in exchange-db/core/apis.py; the PORT env var set in the
k8s manifest is informational only โ like Orcade, Flask's dev server itself
is hardcoded to 0.0.0.0:5000 in run_server()).
3.1 Response envelope
Every endpoint replies with the same envelope, identical to Orcade's:
// success
{ "ok": true, "data": { ... } }
// failure
{ "ok": false, "error": "human readable message" }
3.2 How to submit a task
POST /tasks
Persists the task, then synchronously calls
TaskAssignmentService.assign() โ for function mode this includes the
(blocking) selector-function call; for every mode, the actual delegate
submission always happens on a background thread (see
ยง1.2).
Request body:
| Field | Type | Default if omitted |
|---|---|---|
task_id |
string | server-generated uuid4() |
task_assignment_type |
string | required โ 400 if missing |
task_data |
any | required โ 400 if missing |
task_assignment_status |
string | "pending" |
task_metadata |
object | {} |
curl -X POST http://localhost:5000/tasks \
-H "Content-Type: application/json" \
-d '{
"task_assignment_type": "direct",
"task_data": {"instruction": "summarize this document", "doc_url": "https://storage.example.com/report.pdf"},
"task_metadata": {
"task_assignment": {"subject_id": "agent-summarizer-01"}
}
}'
Response 201 Created:
{
"ok": true,
"data": {
"task_id": "3f9c6d2e-1a2b-4c3d-9e8f-7a6b5c4d3e2f",
"task_assignment_type": "direct",
"task_data": {"instruction": "summarize this document", "doc_url": "https://storage.example.com/report.pdf"},
"task_assignment_status": "pending",
"task_metadata": {"task_assignment": {"subject_id": "agent-summarizer-01"}},
"taski_creation_time": "2026-09-17T10:15:32.481203",
"task_output": {}
}
}
The response is a snapshot from the moment of submission โ for function
mode task_assignment_status will already read "assigned" in the
persisted record (fetch it again via ยง3.3 to see
that), but the object returned inline by this call always reflects the
in-memory task object as it was right after assign() returned, so check
back with a GET rather than trusting this response for anything beyond
task_id.
Failure modes:
| Status | When |
|---|---|
400 |
task_assignment_type or task_data missing from the body |
400 |
assign() raised synchronously โ unsupported task_assignment_type, missing subject_id/function_id in task_metadata.task_assignment, or the selector function (in function mode) raised / didn't return selected_subject_id. The task is still persisted, marked task_assignment_status="failed" with the error in task_output. |
500 |
The initial DB insert itself failed |
3.3 How to read a task
GET /tasks/{task_id} โ full record.
curl http://localhost:5000/tasks/3f9c6d2e-1a2b-4c3d-9e8f-7a6b5c4d3e2f
โ 200 { "ok": true, "data": <ExchangeTasks> }, or 404 if not found.
3.4 How to read task output
GET /tasks/{task_id}/output โ just the two fields callers usually poll for.
curl http://localhost:5000/tasks/3f9c6d2e-1a2b-4c3d-9e8f-7a6b5c4d3e2f/output
{
"ok": true,
"data": {
"task_assignment_status": "completed",
"task_output": {"summary": "...", "acknowledged": true}
}
}
โ 404 if the task doesn't exist. There is no long-poll / websocket
mode โ callers are expected to poll this endpoint themselves.
3.5 Task endpoints โ full reference
| Method | Path | Purpose |
|---|---|---|
POST |
/tasks |
Submit a task (ยง3.2) |
GET |
/tasks/{task_id} |
Fetch one task by ID (ยง3.3) |
GET |
/tasks/{task_id}/output |
Fetch just status + output (ยง3.4) |
POST |
/tasks/query |
Query tasks with a raw Mongo filter |
There is intentionally no PUT/PATCH/DELETE for tasks in this API โ
unlike Orcade's bid jobs, task state is only ever mutated internally by
TaskAssignmentService, not by API callers.
# every task currently sitting in "bidding"
curl -X POST http://localhost:5000/tasks/query \
-H "Content-Type: application/json" \
-d '{"task_assignment_status": "bidding"}'
# every open-mode task that got rejected by all subjects
curl -X POST http://localhost:5000/tasks/query \
-H "Content-Type: application/json" \
-d '{"task_assignment_type": "open", "task_assignment_status": "rejected"}'
Because the filter is passed straight to collection.find(), any valid
Mongo query operator works ($gt, $in, $exists, ...). No projection
support, no auth/ACL layer โ trusted-network only, same as Orcade.
3.6 Subjects โ full reference
| Method | Path | Purpose |
|---|---|---|
POST |
/subjects |
Create a subject |
GET |
/subjects/{subject_id} |
Fetch one subject |
PUT / PATCH |
/subjects/{subject_id} |
Raw $set update; 404 if the subject doesn't exist |
DELETE |
/subjects/{subject_id} |
Delete a subject; 404 if it didn't exist |
POST |
/subjects/query |
Query subjects with a raw Mongo filter |
Create:
curl -X POST http://localhost:5000/subjects \
-H "Content-Type: application/json" \
-d '{
"subject_id": "agent-summarizer-01",
"subject_metadata": {"owner": "team-nlp"},
"task_evaluation_function": "accepts-if-capacity:1.0-stable",
"subject_capabilities": {"max_doc_tokens": 50000},
"topics": ["summarization", "nlp"]
}'
โ 201 { "ok": true, "data": <ExchangeSubjects> }. subject_id is
server-generated if omitted.
Update (unlike Orcade's bid-job update, this one checks existence first and returns the fresh document, not just a modified count):
curl -X PATCH http://localhost:5000/subjects/agent-summarizer-01 \
-H "Content-Type: application/json" \
-d '{"subject_capabilities": {"max_doc_tokens": 80000}}'
โ 200 { "ok": true, "data": <updated ExchangeSubjects> }, or 404 if the
subject doesn't exist.
Delete:
curl -X DELETE http://localhost:5000/subjects/agent-summarizer-01
โ 200 { "ok": true, "data": {"deleted": true} }, or 404 if not found.
Query โ same raw-Mongo-filter convention as /tasks/query:
# every subject that participates in open-mode evaluation
curl -X POST http://localhost:5000/subjects/query \
-H "Content-Type: application/json" \
-d '{"task_evaluation_function": {"$ne": ""}}'
# every subject tagged with the "nlp" topic โ the same filter
# bidding mode itself uses when a task specifies "topics" (ยง4.4, ยง7.2)
curl -X POST http://localhost:5000/subjects/query \
-H "Content-Type: application/json" \
-d '{"topics": {"$in": ["nlp"]}}'
โ Previous: Schema ยท Back to index ยท Next: Assignment modes โ