Seller API keys
A seller API key authenticates your server to the facilitator. It is not a payment credential, and buyers never see one.
What the key looks like
xdcai_live_<keyId>_<secret>
There is no separate access key and secret key. It is one bearer string, with the public keyId embedded in it. The facilitator stores only sha256(keyId || secret), so the secret cannot be recovered by anyone, including us.
| Part | Public | Used for |
|---|---|---|
keyId | Yes | Identifying the key in the dashboard, in logs, and when revoking |
secret | No | Proving the request is yours |
Create one
- Open the facilitator dashboard.
- Choose the address your API is paid at.
- Select New key, label it after the deployment that will use it, and create it.
- Copy the key from the dialog. It is shown once and there is no way to see it again.
Creating a key is not idempotent: pressing the button twice mints two keys. Any signed-in account can create keys for an address it owns, and only for an address it owns.
Use it in your code
One header, on every facilitator call your server makes.
const auth = { Authorization: `Bearer ${process.env.FACILITATOR_API_KEY}` };
await fetch(`${process.env.FACILITATOR_URL}/verify`, { method: "POST", headers: auth, body });
await fetch(`${process.env.FACILITATOR_URL}/settle`, { method: "POST", headers: auth, body });
await fetch(`${process.env.FACILITATOR_URL}/settlements/${id}`, { headers: auth });
Read it from the environment. Do not inline it in source, and do not commit it.
FACILITATOR_API_KEY=xdcai_live_...
Keep it server-side
Anyone holding your key can ask the facilitator to settle payments on your account and can spend your credits. It grants no access to your funds and cannot move USDC out of your wallet, but treat it like a password.
- Never ship it to a browser, a mobile app, or any client-side bundle.
- Never give it to buyers. They do not need one.
- Use one key per deployment, so revoking staging does not break production.
- Keep it out of logs. Log the
keyIdif you need to correlate, never the whole string.
Rate limits
Limits are per key, not per buyer.
| Plan | Requests per minute | Burst |
|---|---|---|
free | 60 | 20 |
payg | 600 | 100 |
enterprise | 3000 | 500 |
Exceeding them returns 429 rate_limited. Note that the limit that applies is the one on the key, not the verifyRpm and settleRpm shown on your plan.
Rotate and revoke
Rotate without downtime:
- Create the new key.
- Deploy it to the server.
- Confirm traffic is flowing.
- Revoke the old key.
Revoking takes effect immediately, and a revoked key returns 401 revoked_key. Revoking a key that is already revoked is safe and does nothing.