API keys
Test and live keys, scopes, IP allowlists, expiry, rolling, revoking, and how live keys are approved.
An API key identifies your workspace and decides what a request may do. Send it on every call as a bearer token:
Authorization: Bearer apk_live_3f9aXyZ…Test and live keys
| Test | Live | |
|---|---|---|
| Starts with | apk_test_ | apk_live_ |
| Money | Simulated. Paid from free test USDC. | Real KES to real people, from your USDC. |
| Available | At once, in any workspace. | After live access is approved, and each key after we approve it. |
| Scopes | Any scope. | Only the capabilities your workspace is approved for. |
| IP allowlist | Optional. | Required for keys with payouts:write. |
| Expiry | 30 days, 90 days, 1 year, or never for read-only keys. | 30 days, 90 days or 1 year. Never isn't allowed. |
Both use the same base URL, https://api.autopayke.com. The key's prefix decides the environment, and objects never cross: a test key can't see live payouts.
Create a key
Open API keys in the Console
Choose Test or Live at the top, then Create key. Owners and admins of the account can create keys; other team members can see them.
Name it
After where it runs: "Production server", "Payroll job". You'll see the name in logs and emails.
Choose scopes
Give each key only what it needs. A reporting job needs read scopes; only the service that pays people needs payouts:write.
Add an IP allowlist
One IP address or CIDR range per line, e.g.
203.0.113.10or198.51.100.0/24. Calls from anywhere else getIP_NOT_ALLOWED. Use your servers' fixed egress addresses (a NAT gateway or static IP), not a laptop or office line.Pick an expiry and confirm
Live keys ask for your PIN, and your authenticator code if you use two-factor sign-in. The key is shown once. We store only a keyed hash and can't show it again.
Live keys are approved one by one
Every new live key, including one made by rolling, starts as Waiting for approval. Our team checks its scopes and allowlist against what your workspace was approved for, usually within one business day, and we email your technical contact either way. Until then, calls with it return KEY_PENDING_APPROVAL. A rejected key returns KEY_REJECTED; the reason is in the Console.
Scopes
| Scope | Unlocks | Notes |
|---|---|---|
account:read | GET /api/v1/account | Read the workspace, key, limits and usage. |
balance:read | GET /api/v1/balance | Read the balance payouts are paid from. |
payouts:read | Quote, list and get payouts | Price payouts and read them. |
payouts:write | POST /api/v1/payouts | Send money. Live keys with it need an IP allowlist. |
recipients:read | POST /api/v1/recipients/verify | Look up the name on a number or bank account. |
transactions:read | Transactions and receipts | Read money movements and receipts. |
events:read | GET /api/v1/events | Read the event log. |
webhooks:write | Webhook endpoints | Create and manage webhook endpoints through the API. |
collections:read / collections:write | Not yet available | Reserved for M-Pesa collections (on-ramp) through the API. |
payment_links:read / payment_links:write | Not yet available | Reserved for payment links through the API. |
batches:read / batches:write | Not yet available | Reserved for bulk payouts. batches:write will need an IP allowlist on live keys. |
A call without the scope it needs gets INSUFFICIENT_SCOPE (403) naming the missing scope. On live keys a scope also has to be one your workspace is approved for; if we take a capability away, keys that still list it stop being able to use it. Request more capabilities on the Console's Live access page.
Presets in the Console: Read only (every :read scope), Payouts (account, balance, payouts, recipients, transactions, events), Full access (everything your plan allows).
Roll a key
Rolling issues a new key with the same name, scopes, allowlist and lifetime, and keeps the old one working for a grace period you choose: immediately, 1 hour, 24 hours or 7 days. Deploy the new key, then let the old one lapse. For a live key, the new key needs our approval first, and the old key keeps working until we approve it; the grace period starts then.
We email the technical contact 30, 7 and 1 days before a key expires, and send an api_key.expiring webhook.
Revoke a key
Revoking is immediate and permanent: the next call gets KEY_REVOKED. Do it the moment a key may have leaked, then create a replacement. Our team can also suspend or revoke a key that's being misused, and will email your security contact.
Keeping keys safe
- Keep keys on servers only: never in a mobile app, browser code, a public repository or a support ticket.
- Store them in a secret manager or environment variables, not in code or config files you commit.
- One key per service and environment, so you can revoke one without stopping the others.
- Up to 10 active keys per environment.
- If a key leaks: revoke it in the Console, create a new one, and check Logs for calls you didn't make.
Anyone with a live key that has payouts:write can send money from your balance, within your limits and from your allowlisted addresses. Treat it like a bank password.