Testing & the sandbox
TreasurySpring provides a sandbox environment so you can build and validate integrations without touching production data. This page covers how to get credentials, along with what the sandbox can and cannot do.
Getting sandbox credentials
Sandbox credentials are self-serve from the TreasurySpring portal:
- Log in to the portal at
https://app.sandbox.treasuryspring.com/portal/profile?tab=developer. - Generate a
client_id/client_secretpair (Client Credentials grant) or request an authorisation-code-flow client. - Use those credentials against the sandbox base URL.
Base URLs
| Environment | Base URL |
|---|---|
| Sandbox | https://api.sandbox.treasuryspring.com/api/v1 |
| Production | https://api.treasuryspring.com/api/v1 |
OAuth token endpoints are at the root of each environment, not under /api/v1:
| Environment | OAuth token endpoint |
|---|---|
| Sandbox | https://api.sandbox.treasuryspring.com/oauth/token |
| Production | https://api.treasuryspring.com/oauth/token |
Exchanging credentials for an access token
- cURL
- Python
curl --location 'https://api.sandbox.treasuryspring.com/oauth/token' \
-H 'Authorization: Basic <base64(client_id:client_secret)>' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=<client_id>' \
--data-urlencode 'client_secret=<client_secret>'
import base64
import requests
basic = base64.b64encode(b"<client_id>:<client_secret>").decode()
resp = requests.post(
"https://api.sandbox.treasuryspring.com/oauth/token",
headers={
"Authorization": f"Basic {basic}",
"Content-Type": "application/x-www-form-urlencoded",
},
data={
"grant_type": "client_credentials",
"client_id": "<client_id>",
"client_secret": "<client_secret>",
},
)
token = resp.json()["access_token"]
expires_in = resp.json()["expires_in"] # seconds until token expires
The response contains an access_token and an expires_in value (in seconds). Cache the token and refresh before it expires; tokens are not single-use.
What the sandbox is
- A separate API and database from production.
- Set up with your own entities and the current indications, with starter holdings on your first entity so you can exercise every read endpoint from day one.
- Runs the FTF lifecycle: subscriptions you submit via
POST /subscribebecome holdings that are issued, cut off, rolled or extended, and redeemed, producing the same events onGET /eventas in production. - Delivers webhooks to your endpoint under the same rules as production, so you can test receiving and verifying them end to end.
- Suitable for end-to-end testing of both the call patterns (auth, request shape, response shape, error handling) and how your system handles a holding's lifecycle.
Starter holdings
When your sandbox access is set up, your first entity (the one ending 0001) is given a few starter subscriptions, depending on what is offered to it:
- two of the shortest fixed-term products, one with a maturity action of
Rolland one ofRedeem; - a fixed-term product of about one month, set to
Hold; - an extendable, set to
Roll.
They are placed the same way as your own subscriptions, so each has a holding that moves through the lifecycle like yours do. On GET /subscription you can tell them apart from your own: signerEmail is sandbox@treasuryspring.com and source is Pre-loaded sandbox subscription. Your other entities start empty.
How the sandbox differs from production
A few differences remain between the sandbox lifecycle and production:
- Processing runs in batches, a few times each business day (currently 08:30, 12:30 and 16:30 London time), rather than at each product's exact cut-off. A status change can lag the real cut-off by a few hours, a 17:00 cut-off is processed the next morning, and a newly issued holding is cut off at the earliest on the following run.
- Issuance does not wait for funds. A holding is issued at the first run on or after its subscription date; there is no cash to send.
- Indications are refreshed daily, so an indication UID can change from one day to the next. Fetch indications on the day you subscribe rather than reusing UIDs.
- Actions our operations team initiates, such as maturity value adjustments, do not happen on their own. Contact TreasurySpring if you need to test them.
Product minimums still apply
Product minimums apply in the sandbox as well as in production. Where an indication's enforceMinimum is true, a subscription below Indication.minimum (in millions) is rejected, so a subscription with amount: 1 will fail; please test with realistic amounts.
Which dataset for what use case
When bootstrapping a historical dataset, the choice of endpoint matters a little more in sandbox than in production:
| Use case | Primary endpoint | Notes |
|---|---|---|
| Initial bulk load of current positions | GET/holding | Authoritative; paginated. |
| Initial bulk load of past subscriptions | GET/subscription | History of intent — terms may differ from the resulting holding. |
| Ongoing T+1 deltas | GET/event | The event stream starts on 2026-04-22. For anything earlier, use the holdings/subscriptions endpoints: the pre-stream history of older positions exists in production only. |
| Current offers | GET/indication/{code} | What is on offer to this entity now. Past offers are not returned, so keep your own record of the terms you subscribed on. |
| Reference data (cells, obligors, calendar) | GET/cell, GET/obligor-exposure, GET/holiday/{year} | Mostly static. |
A typical sandbox session
- Exchange credentials for an access token (above).
- Call GET
/entityto discover entity codes available to this user. - Call GET
/indication/{code}to see what products this entity could subscribe to. - Submit a test subscription via POST
/subscribe. - Inspect GET
/subscriptionfor the resulting record. - Call GET
/holding: your subscription's holding appears asPendingand is issued at the first processing run on or after its subscription date, alongside the starter holdings. - Follow its progress, and the starter holdings', through GET
/event, or register a webhook to have the events sent to you.
Next steps
- Authentication — full OAuth grant-type reference.
- Errors & responses — what failures look like and how to recover.
- Quickstart — end-to-end walkthrough using the sandbox.