Base URL
All API requests should be made to:
https://anderro.com/api/v1
Authentication
Every request must include your secret key in the x-api-key header:
curl -H "x-api-key: sk_your_secret_key" https://anderro.com/api/v1/affiliates
See Authentication for details on finding and managing your API key.
Request format
- All request bodies must be JSON with
Content-Type: application/json - All responses are JSON
Currency
Commissions are computed in USD; non-USD sales are not auto-commissioned yet. Tracking /events payments accept an optional currency field, for example "currency": "USD". Omitted or null currency means amountCents is in USD cents; an explicit non-USD currency is rejected with HTTP 400. Signups ignore currency. Paddle payments with a non-USD or missing currency are skipped; their signups can still be recorded. SamCart payloads carry no currency, so their amounts are treated as USD.
Response envelope
Most endpoints use the following response envelopes:
Single resource:
{
"data": { ... }
}
List (paginated):
{
"data": [ ... ],
"pagination": {
"next_cursor": "...",
"has_more": true
}
}
Error:
{
"error": "Error message",
"details": { ... }
}
Field naming
New endpoints (list, get, update, stats, commissions, payouts) use snake_case field names in responses, consistent with webhook payloads. The original registration and removal endpoints continue to use camelCase for backwards compatibility.
Pagination
List endpoints use cursor-based pagination. See the Pagination guide for details.
| Parameter | Default | Max |
|---|---|---|
limit | 50 | 100 |
cursor | - | - |
Rate limits
All API endpoints are rate-limited to 60 requests per minute per API key. See Rate Limits for details on headers and retry handling.
Request ID
Every response includes an X-Request-Id header with a unique identifier. Include this when contacting support for faster debugging.
Error format
Most errors return a JSON object with a top-level error field:
{
"error": "Validation failed",
"details": {
"fieldErrors": {
"email": ["Invalid email address"]
},
"formErrors": []
}
}
For an invalid period, /api/v1/stats and /api/v1/stats/timeseries return HTTP 400 with this different envelope:
{"data":{"error":"Invalid period. Must be 7d, 30d, 90d, or 12m."}}
HTTP status codes
| Status | Meaning |
|---|---|
200 | Success (update/action) |
201 | Success (resource created) |
400 | Validation error - check request body |
401 | Authentication failed - check API key |
404 | Resource not found |
409 | Conflict - resource already exists or already in target state |
422 | Semantically invalid input (e.g. refund amount exceeds payment) |
429 | Rate limit exceeded - retry after delay |
500 | Internal server error |
Available endpoints
Affiliates
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/affiliates | List affiliates |
GET | /api/v1/affiliates/:id | Get affiliate details |
POST | /api/v1/affiliates | Register a single affiliate |
POST | /api/v1/affiliates/bulk | Register up to 100 affiliates |
PATCH | /api/v1/affiliates/:id | Update affiliate status |
POST | /api/v1/affiliates/remove | Remove a single affiliate |
POST | /api/v1/affiliates/remove/bulk | Remove up to 100 affiliates |
Stats
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/stats | Get summary KPIs |
GET | /api/v1/stats/timeseries | Get daily time series |
Commissions
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/commissions | List commissions |
GET | /api/v1/commissions/:id | Get commission details |
Payouts
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/payouts | List payouts |
GET | /api/v1/payouts/:id | Get payout details |
PATCH | /api/v1/payouts/:id | Update payout (approve/reject/mark paid) |
Refunds
| Method | Endpoint | Description |
|---|---|---|
POST | /api/v1/refunds | Refund a commission |
Customers
| Method | Endpoint | Description |
|---|---|---|
DELETE | /api/v1/customers | Erase end-customer data (GDPR) |