The Allocator API exposes the NTS household optimizer as an asynchronous job service.
Base path (examples):
http://localhost:8082https://api.ntsresearch.net (example only)All routes documented here are relative to the allocator service base.
Every request must include a header:
x-api-token: <token>
Tokens are configured server‑side via the API_TOKENS environment variable (comma‑separated). Requests without a valid token receive 401 Unauthorized.
This is the core job configuration embedded in the submission request.
{
"household_id": "demo-house",
"objective": "custom",
"local_iters": 50,
"grid_step": 0.05,
"n_sims": 1000,
"notes": "optional notes about this run"
}
Fields:
household_id (string, required)
Identifier for the household or scenario. Used for logging and reporting.
objective (string, optional, default "custom")
High‑level optimization objective. Supported values:
"risk_parity""min_var""custom"
local_iters (integer, > 0, default 50)
Number of local search iterations per grid point. Higher = more search, more compute.
grid_step (float, default 0.05)
Coarseness of grid search over key policy parameters (e.g., CRT vs taxable splits).
Smaller steps ⇒ finer search but more total work.
n_sims (integer, > 0, default 1000)
Number of simulation paths used in the optimization.
notes (string, optional)
Free‑form notes stored alongside the job.
Full request payload:
{
"job": { /* AllocJobSpec */ },
"tenant": "nts",
"idem_hint": null,
"dry_run": false
}
Fields:
job (AllocJobSpec, required) – The configuration described above.tenant (string, default "nts") – Logical tenant for multi‑tenant deployments.idem_hint (string, optional) – Optional client‑supplied idempotency hint.dry_run (bool, default false) – If true, the request is validated but not enqueued.Response from the submit endpoint:
{
"accepted": true,
"job_id": "1764792929054-0",
"idem_key": "ops:idem:...",
"message": "Queued"
}
Fields:
accepted (bool) – true if the job was accepted and queued.job_id (string) – Identifier corresponding to the Redis Stream message ID.idem_key (string) – Effective idempotency key used for this job.message (string) – Human‑readable status.The Allocator API enforces lightweight idempotency per job:
idem_hint, it is used to derive an idem_key.idem_hint, the server hashes the request payload to generate one.idem:ops:<idem_key>) with a TTL (e.g., 10 minutes).Semantics:
202 Accepted/200 OK with the same idem_key, but does not enqueue a duplicate message.This protects against client retries while keeping the implementation simple.
/allocator/jobsDescription: Submit a new household optimization job.
Request:
x-api-token: <token>Content-Type: application/jsonSubmitAllocReq as described above.Example:
curl -X POST "$ALLOC_BASE/allocator/jobs" -H "Content-Type: application/json" -H "x-api-token: $API_TOKEN" -d '{
"job": {
"household_id": "demo-house",
"objective": "custom",
"n_sims": 3000,
"local_iters": 4,
"grid_step": 0.10,
"notes": "Quickstart demo"
},
"tenant": "nts",
"dry_run": false
}'
Responses:
200 OK with SubmitAllocAck if queued successfully.400 Bad Request if the payload fails validation.401 Unauthorized if token is missing or invalid.503 Service Unavailable if Redis is unavailable./allocator/jobsDescription: List jobs with optional status filters.
Query params:
status (optional) – one of PENDING, RUNNING, DONE, ERROR.Response:
[
{
"job_id": "1764792929054-0",
"status": "DONE",
"created_at": "2025-12-03T11:40:42.188Z",
"updated_at": "2025-12-03T11:48:31.833Z",
"artifact_s3_key": "jobs/1764792929054-0/report.pptx"
},
{
"job_id": "...",
"status": "RUNNING",
"created_at": "...",
"updated_at": "..."
}
]
/allocator/jobs/{job_id}Description: Fetch detailed status and parameters for a single job.
Path params:
job_id – ID returned by the submit endpoint (Redis Stream ID).Response:
{
"job_id": "1764792929054-0",
"status": "DONE",
"created_at": "2025-12-03T11:40:42.188Z",
"updated_at": "2025-12-03T11:48:31.833Z",
"artifact_s3_key": "jobs/1764792929054-0/report.pptx",
"params": {
"n_sims": 3000,
"n_jobs": 16,
"local_iters": 4,
"grid_step": 0.1,
"start_crt": 8500000.0,
"start_tax": 7500000.0,
"years": 30,
"payout_rate": 0.085
}
}
Errors:
404 Not Found if job_id is unknown./allocator/artifacts/{job_id}/reportDescription: Return a presigned URL to download the PPTX report for a completed job.
Response:
{
"job_id": "1764792929054-0",
"report_url": "https://s3-region.amazonaws.com/nts-household-artifacts/jobs/1764.../report.pptx?X-Amz-Algorithm=..."
}
Notes:
DONE, the server may return 409 Conflict or a similar status to indicate that the artifact is not yet available.Typical lifecycle:
POST /allocator/jobs ⇒ job created, status PENDING.RUNNING.DONE, artifact_s3_key populated.ERROR with an error field describing the issue.The Streamlit demo UI consumes these same endpoints and provides a reference user interface for the API.