Appearance
Authentication
Every request (except /v1/health and /v1/openapi.json) needs an API key. Send it as a bearer token:
bash
curl https://api.textilecredit.com/v1/pools \
-H "Authorization: Bearer tx_live_a1b2c3d4.your_secret_here"The X-API-Key: <key> header works too, if that's easier for your client.
Key format
A key looks like tx_live_a1b2c3d4.<secret>. The part before the dot (tx_live_a1b2c3d4) is the public prefix — it's safe to log and show in dashboards. The part after the dot is the secret. We only store a hash of the secret, so we show you the full key exactly once, when it's issued. If you lose it, ask us to revoke it and issue a new one.
Test vs live
Keys are environment-scoped, and the environment is baked into the prefix:
tx_live_…— mainnet corridors (Ethereum, Polygon, BNB, Base, Celo).tx_test_…— testnet / local chains, kept fully separate from live data.
A test key can't touch a mainnet chain, and vice versa. If you send a chainId your key's environment doesn't allow, you get a 400 invalid_request.
TIP
BNB Smart Chain testnet (chain 97) runs a live cNGN ↔ USDT corridor for integration testing — pass chainId: 97 with a tx_test_… key. See Testnet (BSC) for setup and faucets. Other testnets have no reactor deployed yet; a test key against those chains returns 400 explaining no FX settlement contract is available.
Scopes
Each key is granted a set of scopes. A request to an endpoint you're not scoped for returns 403 forbidden.
| Scope | Grants |
|---|---|
quotes:read | GET /v1/pools, GET /v1/order-book, GET /v1/quote |
trades:write | POST /v1/swaps, POST /v1/swaps/{id}/submit, POST /v1/limit-orders* |
trades:read | GET /v1/swaps*, GET /v1/limit-orders |
webhooks:manage | POST/GET/DELETE /v1/webhooks* |
Ask for the narrowest set you need. A read-only integration only needs quotes:read + trades:read.
Keeping keys safe
- Never ship a
livesecret in client-side code. The API is server-to-server. - Rotate by asking us for a new key, switching over, then revoking the old one.
- A revoked or suspended key returns
401 unauthorized, same as a bad key — we don't distinguish, on purpose.