District Cost Data API
Overview
These ingestion-side routes proxy district cost data from the upstream source system while keeping source-system credentials on the server side.
Direct ingestion paths:
GET /sdac/costsGET /sdac/costs/{cost_id}
Widget same-origin paths:
GET /api/ingestion/sdac/costsGET /api/ingestion/sdac/costs/{cost_id}
Authentication and Access Model
These ingestion routes do not enforce APIM bearer-token or subscription-key validation themselves.
- Browser clients should call the widget same-origin proxy at
/api/ingestion/.... - Direct calls to
/sdac/...should stay behind private networking, host-application controls, or reverse-proxy authentication. - Do not expose the ingestion routes directly to untrusted browser clients.
List Costs
| Attribute | Value |
|---|---|
| Endpoint | GET /sdac/costs |
| Response | JSON |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
district_id | string | No | District identifier used by the source system |
year | integer | No | Filter to a reporting year |
quarter | integer | No | Filter to quarter 1 through 4 |
Response Shape
Successful responses are passed through from the upstream source system without reshaping. Depending on that upstream response, the payload may be:
- a bare array of cost objects
- an object with
sdac_costs - an object with
costs
Example wrapper response:
{
"sdac_costs": [
{
"id": "cst_123",
"district_id": "12345",
"year": 2026,
"quarter": 1
}
]
}
Get Cost Detail
| Attribute | Value |
|---|---|
| Endpoint | GET /sdac/costs/{cost_id} |
| Response | JSON |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
cost_id | string | Yes | Source-system cost identifier returned by the list route |
Response Shape
The detail response is also passed through unchanged. Deployments commonly return either a bare cost object or an object with sdac_cost.
Example detail response:
{
"sdac_cost": {
"id": "cst_123",
"district_id": "12345",
"year": 2026,
"quarter": 1,
"cost_form_primary": true,
"cost_form_records": [
{
"first_name": "Jane",
"last_name": "Doe",
"job_title": "Speech Pathologist"
}
]
}
}
Error Cases
| Status | Description |
|---|---|
| 404 | Upstream cost record not found |
| 500 | Upstream request failed unexpectedly |
| 503 | Server-side source-system configuration is missing |
When the upstream request fails after a connection was established, the service returns:
{
"error": "TherapyLog API request failed",
"upstream_status": 404
}
Operational Notes
- These routes are ingestion-side only and are not exposed through the gateway
/ai/...API. - The browser should use the widget same-origin proxy rather than calling the ingestion service directly.
- Use District Sync API when you need to transform district cost data into an SDAC report and receive a
report_id.