Errors & responses
The API uses standard HTTP status codes and JSON error bodies. This page lists the failure cases that come up most often during integration, what each one looks like, and the recommended client behaviour.
Response shape
Successful responses return the resource (or a paginated envelope). Failures return:
{
"detail": "Human-readable explanation of what went wrong."
}
Validation errors (HTTP 422) include a list of field-level problems:
{
"detail": [
{
"loc": ["body", "amount"],
"msg": "value is not a valid number",
"type": "type_error"
}
]
}
HTTP status code map
| Status | Meaning |
|---|---|
200 | OK — body contains the requested data. |
201 | Created — used by PUT /event/checkpoint/{name} on first-time creation; returns the new resource. |
400 | Bad request — request was syntactically or semantically invalid (see specific cases below). |
401 | Unauthorised — missing or invalid access token. Refresh and retry. |
403 | Forbidden — the access token is valid but does not have permission for this resource (e.g. this entity, this endpoint). See Endpoint permissions. |
404 | Not found — resource does not exist or has been removed. |
409 | Conflict — used by event checkpoints when the expectedCheckpointVersion does not match. |
422 | Unprocessable entity — the request body failed schema validation. |
500 | Internal error — TreasurySpring side. Please retry with backoff; if the issue persists, contact support. |
Common failure cases
Subscription amount below the indication minimum
- Status:
400 - Detail:
Amount is below the indication minimum. - Cause:
amount<Indication.minimum × 1,000,000. Remember the millions vs absolute units rule. - Client behaviour: block the form submission. Recompute the minimum in absolute currency and prompt the user to raise the amount.
Subscription amount above the indication maximum
- Status:
200(subscription accepted with manual-review flag) or400depending onenforceMaximum. - Cause:
amount>Indication.maximum × 1,000,000. - Client behaviour: we'd recommend not hard-blocking above the maximum, since TreasurySpring is often able to accommodate oversize trades at current pricing through manual review. Show a warning, allow submission, and surface that the trade is pending review.
Expired or changed indication UID
- Status:
400or404depending on the failure mode. - Detail:
Indication not foundorIndication is no longer available for subscription. - Cause: For fixed indications, UIDs change daily. Submitting yesterday's
uidagainst today's universe either misses (404) or hits a different product than expected. - Client behaviour: re-fetch GET
/indication/{code}to get current UIDs, then resubmit with a newIdempotency-Key— the previous idempotency key is bound to the previous request and would be replayed. See Identifiers → Indication UIDs.
Missing or duplicate Idempotency-Key header
- Status:
400 - Detail:
Idempotency-Key header is required. - Cause:
POST /subscriberequiresIdempotency-Keyon every request. - Client behaviour: generate a UUIDv4 per logical subscription attempt and reuse the same value across automatic retries of the same logical request. A fresh key is appropriate when the user materially changes the request (for example, a different amount or indication).
Invalid subscription date (closed cut-off)
- Status:
400 - Detail:
Subscription date is not a valid date for this indication. - Cause: The
subscriptionDatesent is not in the indication'ssubscriptionDateslist, or has already passed cut-off. - Client behaviour: please submit dates listed in
Indication.subscriptionDates. IfsubscriptionDateis omitted, the server defaults to today; if today's cut-off has already passed, the subscription is retargeted to the next available date (this is not an error — see late funding behaviour).
Insufficient permissions
- Status:
403 - Detail:
Not authorised for this entityorEndpoint not enabled for this API user. - Cause: Two distinct cases. The entity isn't on this user's allow-list, or the endpoint itself isn't provisioned for this client (some integrators are scoped to read-only endpoints).
- Client behaviour: retrying on
403won't help — please contact your TreasurySpring account manager to extend access. See Endpoint permissions.
Late funding
This is not an error. If the wire arrives after the requested subscriptionDate cut-off, TreasurySpring re-targets the subscription to the next available subscription date for the same FTF. The resulting holding will simply show a later subscriptionDate. See FTF Lifecycle → Subscription, funding, and late wires.
Polling pattern: holding is the source of truth
After POST/subscribe, the response gives you a subscription uid immediately. The holding may not exist yet — issuance is a downstream process.
The recommended pattern:
POST /subscribe→ getsubscription.uid.- Poll GET
/subscription(filtered byentity_code) every 30–60 seconds. - When
subscription.holdingUidis non-null, switch to keying on the holding via GET/holding/{entity_code}/{holding_uid}. - Stop polling once the holding status is
Issued(or terminal:Cancelled).
It's worth noting that a holding not appearing within the first few minutes isn't a sign of failure — issuance is tied to cut-off rather than request time. A subscription submitted at 09:00 for a product with a 12:15 cut-off will not issue until after 12:15.
Idempotency on retry
If the network drops mid-request and you cannot tell whether the server received your subscription, please retry with the same Idempotency-Key. TreasurySpring will replay the cached response (whether success or rejection) rather than re-processing. A fresh key is appropriate only when you're submitting a materially different request.
Webhooks for delivery confirmations
Webhook URLs can be registered via POST/webhook and deregistered via DELETE/webhook, but no events are delivered to those URLs today. For lifecycle reconciliation, we'd suggest the event stream with cursor pagination or a checkpoint.