Skip to main content

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

StatusMeaning
200OK — body contains the requested data.
201Created — used by PUT /event/checkpoint/{name} on first-time creation; returns the new resource.
400Bad request — request was syntactically or semantically invalid (see specific cases below).
401Unauthorised — missing or invalid access token. Refresh and retry.
403Forbidden — the access token is valid but does not have permission for this resource (e.g. this entity, this endpoint). See Endpoint permissions.
404Not found — resource does not exist or has been removed.
409Conflict — used by event checkpoints when the expectedCheckpointVersion does not match.
422Unprocessable entity — the request body failed schema validation.
500Internal 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) or 400 depending on enforceMaximum.
  • 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: 400 or 404 depending on the failure mode.
  • Detail: Indication not found or Indication is no longer available for subscription.
  • Cause: For fixed indications, UIDs change daily. Submitting yesterday's uid against 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 new Idempotency-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 /subscribe requires Idempotency-Key on 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 subscriptionDate sent is not in the indication's subscriptionDates list, or has already passed cut-off.
  • Client behaviour: please submit dates listed in Indication.subscriptionDates. If subscriptionDate is 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 entity or Endpoint 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 403 won'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:

  1. POST /subscribe → get subscription.uid.
  2. Poll GET/subscription (filtered by entity_code) every 30–60 seconds.
  3. When subscription.holdingUid is non-null, switch to keying on the holding via GET/holding/{entity_code}/{holding_uid}.
  4. 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.