Download OpenAPI specification:
HTTPS mailbox for TDS CSV profile files, for providers that can only call out.
The relay mailbox (SPEC.md §9.4) moves CSV profile files (SPEC.md §9.2) between a requester and a provider whose scheduler cannot accept connections: behind an agency firewall, or inside a platform such as Google Apps Script. Unlike spec/openapi.yaml, it is served by the requester (broker or coordinator tool), and the provider's agent is the client. The agent lists the request files waiting, downloads each one, acknowledges it once it is safely stored, and uploads answers and statuses files. Every call is safe to repeat: acknowledgements are idempotent and uploads are write-once by name, so no Idempotency-Key is used. The credential names one provider's mailbox; the provider is never taken from the request.
Request files the agent has not acknowledged yet, oldest first, with each file's size and SHA-256, the provider whose mailbox this is, and the poll interval the requester expects (SPEC.md §9.4). Every authorised call counts as a poll; an agent that has a file already (same name and SHA-256) acknowledges it again instead of downloading it.
| X-Relay-Agent | string <= 80 characters Optional |
| provider_id required | string non-empty The provider whose mailbox this is, taken from the credential. The same id the provider uses in the files' |
| poll_interval_s required | integer >= 1 Seconds the requester expects between an agent's calls. Agents SHOULD poll about this often and no more often, apart from retries; a requester MAY report an agent as silent after three intervals without a call. |
| requester_id | string non-empty The requester serving the mailbox, as it appears in the files' |
| upload_reports | boolean True when GET /inbox/{file_name} reports what became of each uploaded file's rows (SPEC.md §9.4). Absent or false: the requester does not report, and that call is 404. |
| max_file_bytes | integer >= 1000000 Largest upload, in bytes, PUT /inbox/{file_name} accepts; larger files are refused with FILE_TOO_LARGE (413). At least 1000000 when given. |
required | Array of objects (MailboxFile) Request files not yet acknowledged, oldest first (by created_at, then name). |
{- "provider_id": "county-dial-a-ride",
- "poll_interval_s": 300,
- "max_file_bytes": 10485760,
- "files": [
- {
- "name": "tds_requests_20261104T150000Z.csv",
- "size": 1198,
- "sha256": "57dd4befc5ddd8a97df0ab5cff0fd86282dccf3a5e3990db4d804cff57e3b673",
- "created_at": "2026-11-04T15:00:00Z"
}
]
}One request file's bytes (SPEC.md §9.4). The agent checks X-Relay-SHA256 (and the listing's sha256) against the bytes before saving the file, and acknowledges it only after it is safely stored. A file stays downloadable after its acknowledgement until the requester deletes it under its retention rules. Reading a file changes nothing.
| file_name required | string [ 1 .. 128 ] characters A file name in the relay mailbox (SPEC.md §9.4): letters, digits, |
| X-Relay-Agent | string <= 80 characters Optional |
| X-Relay-SHA256 | string^[0-9a-f]{64}$ Example: "57dd4befc5ddd8a97df0ab5cff0fd86282dccf3a5e3990db4d804cff57e3b673" SHA-256 of the response body, lowercase hex (SPEC.md §9.4). Equals the |
requester_id,provider_id,trip_id,leg_id,action,revision,rider_ref_id,rider_display_name,rider_language,rider_contact_consent,rider_phone,attendants,pickup_lat,pickup_lon,pickup_name,pickup_street,pickup_city,pickup_region,pickup_postal_code,pickup_country,dropoff_lat,dropoff_lon,dropoff_name,pickup_earliest,pickup_latest,dropoff_earliest,dropoff_latest,service_requirements,notes_to_driver,funding_source,authorization_ref throughride-demo,county-dial-a-ride,tr-20261105-0001,leg-1,REQUEST,1,r-91c2,Ana,es,true,+15175550142,1,42.2601,-83.7795,Home,210 Example St,Ann Arbor,MI,48103,US,42.2836,-83.7286,"Regional Hospital, east entrance",2026-11-05T08:00:00-05:00,2026-11-05T08:30:00-05:00,,,WHEELCHAIR_LIFT|DOOR_TO_DOOR,"Ring bell twice, ramp at side door",MEDICAID_NEMT,PA-55120 throughride-demo,county-dial-a-ride,tr-20261105-0002,leg-1,REQUEST,1,r-4be0,,,,,,42.2215,-83.687,,,,,,,42.2475,-83.7426,Senior Center,,,2026-11-05T09:30:00-05:00,2026-11-05T10:00:00-05:00,,,SECTION_5311, throughride-demo,county-dial-a-ride,tr-20261105-0003,leg-1,REQUEST,1,r-77d1,,,,,,42.2601,-83.7795,,,,,,,42.9634,-85.6681,Out-of-area destination,2026-11-05T07:00:00-05:00,2026-11-05T07:30:00-05:00,,,,,RIDER,
The agent has the file safely stored; it leaves the listing (SPEC.md §9.4). Idempotent: acknowledging again returns 200 with the first acknowledgement's time. An agent that crashes between download and acknowledgement sees the file listed again and acknowledges it then. No request body and no Idempotency-Key.
| file_name required | string [ 1 .. 128 ] characters A file name in the relay mailbox (SPEC.md §9.4): letters, digits, |
| X-Relay-Agent | string <= 80 characters Optional |
| name required | string non-empty The acknowledged file's name. |
| acked_at required | string <date-time> When the file was first acknowledged (RFC 3339). Later acknowledgements do not change it. |
{- "name": "tds_requests_20261104T150000Z.csv",
- "acked_at": "2026-11-04T15:04:10Z"
}Store an answers or statuses file (SPEC.md §9.2) for the requester to read, write-once by name (SPEC.md §9.4). The body is the file's raw bytes. A new name is stored (201); the same bytes under a stored name are a retry (200, applied once); other bytes under a stored name are refused (409 FILE_NAME_TAKEN) and never overwrite the stored file, so new content needs a new name. Names MUST follow SPEC.md §9.2 for answers or statuses files. No Idempotency-Key: the name is the key.
| file_name required | string [ 1 .. 128 ] characters A file name in the relay mailbox (SPEC.md §9.4): letters, digits, |
| X-Relay-Agent | string <= 80 characters Optional |
| name required | string non-empty The stored file's name. |
| stored required | boolean True when this upload stored the file; false when the same bytes were already there. |
| sha256 required | string^[0-9a-f]{64}$ SHA-256 of the stored bytes, lowercase hex, so the agent can confirm what arrived. |
| size | integer >= 1 Length of the stored file in bytes. |
| received_at | string <date-time> When the file was first stored (RFC 3339). A retry does not change it. |
| name required | string non-empty The stored file's name. |
| stored required | boolean True when this upload stored the file; false when the same bytes were already there. |
| sha256 required | string^[0-9a-f]{64}$ SHA-256 of the stored bytes, lowercase hex, so the agent can confirm what arrived. |
| size | integer >= 1 Length of the stored file in bytes. |
| received_at | string <date-time> When the file was first stored (RFC 3339). A retry does not change it. |
requester_id,provider_id,trip_id,leg_id,action,revision,result,status,provider_trip_id,scheduled_pickup,scheduled_dropoff,reason,answered_at throughride-demo,county-dial-a-ride,tr-20261105-0001,leg-1,REQUEST,1,ACCEPTED,CONFIRMED,CDR-31877,2026-11-05T08:10:00-05:00,2026-11-05T08:55:00-05:00,,2026-11-04T15:40:00-05:00 throughride-demo,county-dial-a-ride,tr-20261105-0002,leg-1,REQUEST,1,ACCEPTED,CONFIRMED,CDR-31878,2026-11-05T09:05:00-05:00,,,2026-11-04T15:40:00-05:00 throughride-demo,county-dial-a-ride,tr-20261105-0003,leg-1,REQUEST,1,REJECTED,REJECTED,,,,OUTSIDE_SERVICE_AREA,2026-11-04T15:40:00-05:00
{- "name": "tds_answers_20261104T204000Z.csv",
- "stored": false,
- "sha256": "eef2ac1723c655b97791b6abcf0e37944ccafe6e0d05bb9c104e52c36701e7cf",
- "size": 611,
- "received_at": "2026-11-04T20:40:05Z"
}The requester's report on an answers or statuses file this agent uploaded (SPEC.md §9.4): RECEIVED until it is read, then PROCESSED with counts and an entry for every row not applied (DUPLICATE, or REJECTED with a code and, when one cell is at fault, its column), or REFUSED when the file could not be read at all. Only for requesters whose listing says upload_reports: true; others answer 404. Reports hold row numbers, column names and codes, never cell contents, and are kept at least 7 days after the file was read. Reading a report changes nothing.
| file_name required | string [ 1 .. 128 ] characters A file name in the relay mailbox (SPEC.md §9.4): letters, digits, |
| X-Relay-Agent | string <= 80 characters Optional |
| name required | string non-empty The uploaded file's name. |
| sha256 required | string^[0-9a-f]{64}$ SHA-256 of the stored bytes, lowercase hex, as in the upload receipt. |
| received_at required | string <date-time> When the file was first stored (RFC 3339). |
| status required | string Enum: "RECEIVED" "PROCESSED" "REFUSED" RECEIVED (not read yet), PROCESSED (read row by row) or REFUSED (unreadable as a whole). Value: "REFUSED" |
| processed_at required | string <date-time> When the requester read the file (RFC 3339). Present once PROCESSED or REFUSED. |
| refusal required | string Enum: "INVALID_ENCODING" "INVALID_HEADER" "OTHER" Why a REFUSED file could not be read: INVALID_ENCODING (not UTF-8), INVALID_HEADER (no header row, a duplicate or unnamed column, or a required column missing), OTHER. Unknown values must be treated as OTHER. |
| row_count | integer >= 0 Data rows read (the header and rows with no cells not counted). |
| applied_count | integer >= 0 Rows applied. |
| duplicate_count | integer >= 0 Rows that repeated a row already applied and changed nothing. |
| rejected_count | integer >= 0 Rows not applied; each is listed in |
Array of objects (MailboxRowOutcome) Every row not applied, in file order. Empty when every row was applied. |
{- "name": "tds_answers_20261104T204000Z.csv",
- "sha256": "eef2ac1723c655b97791b6abcf0e37944ccafe6e0d05bb9c104e52c36701e7cf",
- "received_at": "2026-11-04T20:40:05Z",
- "status": "PROCESSED",
- "processed_at": "2026-11-04T20:41:00Z",
- "row_count": 3,
- "applied_count": 3,
- "duplicate_count": 0,
- "rejected_count": 0,
- "rows": [ ]
}