Why you need one
Two reasons, one of which matters today and one of which matters soon. Today: it makes your traffic yours. Requests carrying your key are attributed to your organisation. That is what lets SODAX see your integration’s usage separately from anonymous traffic — the basis for supporting you, for raising your limits, and for the per-organisation usage view in the portal. Soon: it will be required. The write paths of the Swaps and Leveraged Yield APIs are already wired for key checking. It is currently switched off on the public deployments and will be turned on route by route, deployment by deployment. Integrations already sending a valid key when that happens keep working with no change; integrations sending nothing start receiving401.
So the useful thing to do now is create a key, deploy it, and forget about it. The switch then costs you nothing.
A key is not enforced anywhere yet, so you cannot test that yours works. Requests with no key, and requests with a wrong or revoked key, are both served normally today. Do not read a
200 as evidence your key is valid — check the prefix against the portal instead.What a key does and doesn’t cover
Key checking is per route, and only the routes that make the backend do something carry it.
Enforcement has three states per deployment — off, monitor, and enforce. Monitor runs the identical check and records the outcome without rejecting anything; a route only moves to enforce after a period of monitoring shows no legitimate traffic arriving without a key. Rollback is a return to monitor.
What an API key is
A SODAX API key is a secret string your server attaches to each HTTP request so the API knows which organisation is calling. It is the literalsodax_ prefix followed by 32 random bytes in base64url:
A leaked API key lets someone else make API calls attributed to your organisation. It does not let them touch anyone’s funds. Users still sign their own transactions with their own wallets.
Who can create one
Keys belong to an organisation, not to a person. You need a partner portal account that is a member of one.
Members see each key’s name, its non-secret prefix, its permissions and when it was created — never the secret itself, which nobody can read back after creation.
Creating a key
The full key is displayed exactly once, at the moment you create it. It is stored as a SHA-256 hash, so it cannot be shown again, recovered, or emailed to you. If you navigate away before copying it, that key is unusable and the only fix is to revoke it and create another. Have somewhere to paste it before you click Create.- Open the API keys panel in the partner portal and choose your organisation.
- Enter a name, up to 64 characters — for example
productionorstaging-worker. - Click Create key.
- Copy the full key from the panel and store it (see Where to put it).
- Click Done to dismiss the reveal.
sodax_ plus the first eight characters of the secret, like sodax_8Kj2mNp4 — followed by dots. The prefix is not secret; it exists so you can tell which stored key is which.
Where to put it
The key belongs on a server you control, loaded from the environment or a secret manager.
Anything a browser downloads is readable by whoever downloaded it, so a key in front-end JavaScript is a published key. If your front end needs SODAX data, proxy the call through your own backend and attach the key there.
The header
The key goes in anx-api-key request header.
sodax.api.swaps, sodax.api.bridge, the solver API, and the backend submit-tx legs of sodax.swaps.swap() and sodax.bridge.bridge(). Sponsoring is the exception — see below.
headers['x-api-key'] beats the apiKey option in both packages. The SDK resolves a longer precedence chain for per-call overrides — see Configure SDK for the full order.
Permissions
Every key minted from the portal carries both scopes. Scopes are fixed server-side — the portal offers no picker, and you cannot request a narrower or wider key. A SODAX operator can narrow a specific key afterwards if you ask.
The split follows what a call causes, not its HTTP verb. Verb is a poor guide here because many read-only calls are POSTs — a quote request carries a body that will not fit in a query string. Both scopes cover the Leveraged Yield routes too, which reuse the same vocabulary rather than defining their own.
Two keys, and why
An organisation may hold two active keys at once. This is the rotation mechanism, not a quota — the second slot exists so you always have somewhere to put the replacement. Rotating without downtime:- Create the second key in the portal. Both keys now work.
- Deploy it — update the secret everywhere your code reads it, and confirm the new key is live in every environment and region.
- Revoke the first key.
Revoking a key
Revoking deletes the key. It is not a disable, there is no revoked state, and there is nothing to restore. If you revoke the wrong key, the fix is to create a new one and deploy it. The portal asks you to confirm, and warns you when the key you are revoking is your organisation’s only one. Revocation is not instant. Each API service holds a cached copy of the active key set and refreshes it every 15 seconds, so a revoked key usually stops working within about 15 seconds. It can take longer: a service that cannot refresh its copy keeps serving the last good one rather than failing closed, and there is no guaranteed ceiling. Treat revocation as prompt, not immediate — if a key has leaked, revoke it and then confirm the leak is contained by other means.When something goes wrong
Once enforcement is enabled on a route, a rejected request looks like this:
Both
@sodax/sdk and @sodax/swaps-api already retry that 503 for you, with backoff, and treat it as safe to replay even for a mutation — the request was rejected before it reached the route handler. You should not need to handle it yourself.
Errors from the portal while managing keys:
A create request that never confirms
If creating a key fails with a503 or the request never completes, do not retry it. The key is generated inside the API and the plaintext is returned exactly once, so a request that reached the server but never got back to you may have created a real key that nobody holds — one that occupies a slot and can never be used.
Refresh the key list first and see what actually exists:
- A new key is listed that you don’t hold the secret for → revoke it, then create a replacement.
- Nothing new is listed → the mint didn’t happen. Create again.
Sponsoring keys are separate
The Stellar Sponsoring API (/v1/sponsorships/*) also uses an x-api-key header, and it does enforce it today — but it runs on its own separate key registry. A key you mint in the partner portal will not work there, and a sponsoring key will not work on the swaps routes.
Sponsoring keys are not self-serve. Request one from the SODAX team, as described on that page.
If you use both, set the sponsoring key on its own config slice —
api.sponsoringApiConfig.apiKey. Without it, an instance-wide new Sodax({ apiKey }) will reach sponsoring whenever the call targets a SODAX gateway root, and a portal key sent there is rejected.Get help
Discord
Integration questions, including anything about keys and enforcement timing.
Contact the team
Partnerships, org and role changes, and narrowing a key’s scopes.