Pilot environment: testnet, simulated yield, mocked fiat rails — read the disclosure
Using the API

Go live

The checklist to work through before you point real volume at this integration, and what happens next.

There is no production environment yet

Everything below is worth doing now. None of it can be exercised against real money today. The pilot is a testnet with mocked fiat rails and simulated yield: see the disclosure above and Environments. Contact partners@threecomma.group before you plan a launch date, and do not commit to one on the strength of these docs.

Money handling

Mint an idempotency key before every money call, and reuse it on retry

Generate the key at the moment you decide to move money, persist it beside your own record of that movement, and send the same one on every attempt. A retry path that generates a fresh key moves money twice.

Verify: kill your process mid-deposit, restart it, and confirm the resumed attempt sends the key that was already persisted.

Handle every terminal state, including the compensable ones

SETTLED and FAILED are straightforward. Your code must also handle FAILED_PENDING_COMPENSATION and COMPENSATED, which means routing them to a person rather than to a retry queue.

Design against one failure mode: treating "not settled" as "failed, so retry". On a withdrawal that is how the same shares leave the vault twice. See the money lifecycle.

Verify: your state machine has an explicit branch for all six states, and none of them falls through to a resubmit.

Never resubmit a *_PENDING_COMPENSATION or *_SETTLEMENT_NOT_RECORDED

Both mean money moved. Poll the original key; escalate to your operations team and to TCB. A new key is a second movement.

Verify: grep your codebase for the retry path and confirm these codes cannot reach it.

Read your position from the API, not from your own arithmetic

Do not maintain a running share balance by adding up your own deposits. Reconcile against GET /positions on a schedule and alert on any divergence. A disagreement between your book and the ledger is what you most want to find early.

Webhooks

Verify the signature on every single delivery

An unverified webhook is an unauthenticated HTTP request from the internet. Recompute the HMAC over the exact raw body, before any JSON parsing or re-serialisation, and compare in constant time. During a secret rotation two signatures are present and a match on either is valid. Reject a stale timestamp; five minutes is a reasonable tolerance.

Verify: send a request to your endpoint with a wrong signature and confirm it is rejected. The webhooks guide has working code.

Deduplicate on the event id

Delivery is at-least-once and ordering is not guaranteed. Store the tcb-webhook-id and drop a repeat. Make the handler itself idempotent too. A duplicate deposit.settled must not credit your customer twice.

Treat the webhook as a signal, not as data

Payloads are thin: an id, a type and a pointer. Fetch the object from its read endpoint and act on that. Never act on the pointer alone.

Return 2xx fast, and do the work afterwards

Acknowledge within a few seconds and process asynchronously. A slow handler turns into a retry, and a retry ladder that runs out marks the delivery exhausted.

Have a plan for a missed event

Nothing re-sends a delivery on a timer once its ladder is spent. Reconcile periodically against the read endpoints, so a lost webhook becomes a delay rather than a silent gap.

Credentials

Store the API key in a secret manager

Not in source control, not in a container image, not in a build log, never in anything a browser or mobile app can reach. The key authenticates your whole tree.

Hold the narrowest scope list that works

A reporting job should not be holding vault:withdraw. Ask TCB for separate keys with separate scopes per system, and use the keyPrefix in your logs to tell which one acted.

Deploy the new secret before you request a rotation

API key rotation has no overlap window. The old key stops working the instant the new one exists. Webhook signing secrets behave differently: those rotate with an overlap, and both signatures are valid during it.

Know how to revoke

You cannot revoke your own key. If one leaks, contact partners@threecomma.group immediately. Have that path rehearsed before you need it.

Operations

Monitor 429s

There are no rate-limit headers to read your remaining budget from, so a 429 is your only signal. Alert on the rate of them, back off to the start of the next minute, and ask TCB to raise your limit before you need it rather than after.

Log the code, the message and your idempotency key together

Those three resolve almost every support request. The message on a money error states what did and did not move. Keep it in full, even though you branch on code.

Alert on PARTNER_RAIL_FROZEN

It means TCB stopped your rail on one vault after finding a divergence it could not explain. Retrying cannot clear it and only a person lifts it. Page someone.

Ignore unknown response fields

Within v1, new response fields appear without warning. A client that fails on one breaks on an additive release that breaks nobody else.

When you are ready

Contact partners@threecomma.group to discuss a stg_ key, your rate limit, per-key sub-client restrictions, and what comes after the pilot.

Pilot disclosure

On this page