Skip to content

โ† Back to index

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 โ†’