This page shows developers how to create an AffiliateBase API key, authenticate requests to the account-scoped REST API under /api/v1, limit a key with permissions, and handle rate limits.
For full details, see:
Create an API key
In the app, owners and admins can create a key in Settings -> API keys: enter a Key name, choose Expires after (30 days, 90 days, 1 year by default, or No expiry), then choose Create key. Keys created in the app have full access. The expiry date and last use appear in the Active API keys list, and expired keys are marked Expired.
Through the API, use these endpoints:
The API returns a key secret once, when you create the key. Keys created through the API do not expire unless you set expires_at.
Authenticate requests
The REST API accepts these auth headers:
Authorization: Bearer <API_KEY>Authorization: Basic <base64(API_KEY:)>X-Api-Key: <API_KEY>
Only AffiliateBase API keys work at /api/v1. Access tokens issued to AI connectors through OAuth (for example, ChatGPT connectors) are refused at /api/v1 with 403 and the code FORBIDDEN, even if the token’s permissions would otherwise allow the request. Those tokens work only at the MCP endpoint. See AI Connectors and MCP.
Scope requests to your account
Provide account context with one of:
?account_id=<ACCOUNT_ID>X-Account-Id: <ACCOUNT_ID>
/api/v1 requests without account context return:
{ "error": "Account ID is required", "code": "MISSING_ACCOUNT_ID" }Quick example
curl "https://app.affiliatebase.io/api/v1/affiliates?account_id=<ACCOUNT_ID>&page=1&limit=25" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: application/json"Limit a key with permissions
When you create a key through POST /api/v1/api_keys, permissions is required and must be a non-empty object. A request that omits permissions, sends an empty object, or sends a non-object returns 422 with the code VALIDATION_ERROR. For full access, send { "all": true }. Keys created in the app always have full access.
Example request body for a read-only affiliates key:
{
"name": "Read-only affiliates",
"permissions": {
"v1.affiliates.read": true
}
}Permission names
A non-full-access key is checked against the resource and action of each request. Read requests (GET) need the read action. All other methods need write. Permission names take the form v1.<resource>.<action>, for example v1.commissions.read. These resources are available:
| Resource | Covers |
|---|---|
affiliates | Affiliates (banning needs a separate exact permission, below) |
affiliate_coupons | Affiliate coupons and individually assigned promo codes |
campaigns | Campaigns |
referrals | Referrals |
commissions | Commissions and commission fraud review |
payouts | Payouts and marking a payout paid |
payout_exports | Payout exports and export payments |
payout_runs | Payout runs |
links | Links |
invitations | Invitations and resending invitations |
Manage API keys through the API
Creating and changing keys through the API requires either a full-access key or a key that holds exactly v1.api_keys.manage. Broad permissions such as write do not grant it. A key can only create keys whose permissions it already holds, so a scoped key cannot mint a full-access key. Dashboard users still need the owner or admin role to manage keys.
Ban affiliates
POST /api/v1/affiliates/:id/ban and /unban require the exact permission v1.affiliates.ban. Full-access keys (all or *) have it. Broad permissions such as write, v1.affiliates.write, or scoped wildcards like v1.affiliates.* do not grant it, so a key that can edit affiliates cannot ban them unless you add the permission on purpose:
{
"name": "Fraud tooling",
"permissions": {
"v1.affiliates.read": true,
"v1.affiliates.ban": true
}
}A key that manages API keys can only give v1.affiliates.ban to a new key when it holds that permission itself. Dashboard users need the owner or admin role to ban or unban through the API.
Key lifetime and creator
Keys stop working when the team member who created them is removed from the account. Create long-lived integration keys from a user account that will stay on the team.
A full-access key acts as the team member who created it. A scoped key never inherits its creator’s role, so it cannot grant the owner role even if its creator is an owner.
Rate limits
/api/v1 requests are limited per credential and per IP address.
| Limit | Value |
|---|---|
| Per API key (or dashboard session) | 45 requests per 30 seconds |
| Per IP address, across all keys | 180 requests per 30 seconds |
When a limit is exceeded, the API returns 429 Too Many Requests with the error code TOO_MANY_REQUESTS and these headers:
RateLimit-Limit: 45
RateLimit-Remaining: 0
RateLimit-Reset: 30
Retry-After: 30These headers are sent on 429 responses only, not on every response. Wait for Retry-After seconds before retrying, and back off if you keep receiving 429. Integrations that run several keys from one IP address share the per-IP limit.
Promo-code permissions
Individually assigned promo-code reads use v1.affiliate_coupons.read; previews and writes use v1.affiliate_coupons.write. These REST permissions are separate from the mcp.affiliate_coupons.read / mcp.affiliate_coupons.write connector permissions. See the promo-code REST reference or MCP guide.
What the API currently covers
- API keys
- Affiliates
- Affiliate coupons and individually assigned promo codes
- Campaigns
- Referrals
- Commissions
- Payouts
- Payout exports
- Payout runs
- Links
- Invitations