Public API Status
The FyberPay public REST API is coming soon . Today, all platform functionality is accessed
through the web dashboard and subscriber portal. This reference documents the internal API
surface that the public API will mirror once released.
When the public API launches, you will be able to manage subscribers, invoices, payments, plans,
and network provisioning programmatically. Subscribe to the FyberPay blog
for launch updates.
Base URL
FyberPay uses subdomain-based multi-tenancy. Every API request is scoped to an organization by its
subdomain:
https://{orgSlug}.api.fyberpay.com
Environment Pattern Production https://{orgSlug}.api.fyberpay.comPlatform admin https://api.fyberpay.com (super_admin only)
Replace {orgSlug} with your organization’s slug. For example, if your ISP’s slug is acme:
https://acme.api.fyberpay.com/subscribers
Authentication
FyberPay supports two authentication methods:
Session Cookies JWT access and refresh tokens delivered as httpOnly cookies. Used by the web dashboard and
subscriber portal automatically.
API Keys Bearer token authentication for server-to-server integrations. Pass the key in the
Authorization header. Available when the public API launches.
Cookie-based auth (web clients)
After a successful login, the server sets two httpOnly cookies:
Cookie Purpose Lifetime access_tokenJWT for request authentication 15 minutes refresh_tokenOpaque token for obtaining new access tokens 7 days
Cookies are scoped to .fyberpay.com so they work across subdomains.
API key auth (server-to-server)
API keys will be available when the public API launches. The format is documented here for
early reference.
curl https://acme.api.fyberpay.com/subscribers \
-H "Authorization: Bearer fybr_live_abc123..."
See Authentication for full details on login flows and token
management.
Rate Limiting
All endpoints are rate-limited to protect platform stability.
Scope Limit Authenticated requests 300 requests per minute per user Login / OTP endpoints 10 requests per minute per IP Webhook callbacks 100 requests per minute per gateway
When you exceed a limit, the API returns 429 Too Many Requests with a Retry-After header
indicating how many seconds to wait.
All errors follow a consistent JSON structure:
{
"statusCode" : 422 ,
"message" : "Validation failed: email must be a valid email address" ,
"error" : "Unprocessable Entity"
}
Field Type Description statusCodenumberHTTP status code messagestring or string[]Human-readable error description. Validation errors may return an array of messages. errorstringHTTP status text
Common status codes
Code Meaning 400Bad Request. Malformed input or missing required fields. 401Unauthorized. Missing or expired authentication. 403Forbidden. Authenticated but lacking permission for this action. 404Not Found. Resource does not exist or is outside your tenant scope. 409Conflict. Duplicate idempotency key is still being processed. 422Unprocessable Entity. Input validation failed. 429Too Many Requests. Rate limit exceeded. 500Internal Server Error. Unexpected failure; contact support.
List endpoints use cursor-based pagination for consistent, performant results.
Request parameters
Parameter Type Default Description cursorstring(none) Opaque cursor from a previous response. Omit for the first page. limitnumber25Number of items per page. Maximum 100.
Response shape
{
"data" : [ ... ],
"nextCursor" : "eyJpZCI6IjAxOTVkZTBhLTkz..." ,
"hasMore" : true
}
Field Type Description dataarrayThe page of results nextCursorstring or nullPass this as the cursor parameter to fetch the next page. null when there are no more results. hasMorebooleantrue if additional pages exist
Example
# First page
curl https://acme.api.fyberpay.com/subscribers?limit= 10
# Next page
curl https://acme.api.fyberpay.com/subscribers?limit= 10 & cursor = eyJpZCI6IjAxOTVkZTBhLTkz...
Idempotency
Mutation endpoints (POST, PUT, PATCH, DELETE) support idempotency to safely retry requests without
causing duplicate side effects, such as double-charging a subscriber.
How it works
Generate a unique key (a UUID v4 works well) and include it in the Idempotency-Key header.
The server processes the request and caches the response for 24 hours .
Any subsequent request with the same key returns the cached response without re-executing the
operation.
curl -X POST https://acme.api.fyberpay.com/payments/initiate \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-H "Content-Type: application/json" \
-d '{"subscriberId": "sub_123", "amount": 2500}'
Behavior details
Scenario Result First request with a new key Processed normally; response cached Repeat request with a completed key Cached response returned (no re-processing) Repeat request while original is still processing 409 Conflict returnedRequest fails with an error Key is cleared so you can safely retry No Idempotency-Key header provided Request processed without caching (backward compatible)
Idempotency keys expire after 24 hours. If you retry a request after that window, it will be
processed as a new request.
Webhook Delivery
FyberPay delivers webhooks for payment events, subscription lifecycle changes, and network
provisioning updates. Webhooks are sent as POST requests to your configured endpoint.
{
"id" : "evt_01H5K3XYZABC" ,
"type" : "payment.succeeded" ,
"orgId" : "org_01H5K3..." ,
"timestamp" : "2026-03-22T10:30:00.000Z" ,
"data" : {
"paymentId" : "pay_01H5K3..." ,
"subscriberId" : "sub_01H5K3..." ,
"amount" : 2500 ,
"currency" : "KES" ,
"gateway" : "mpesa_stk"
}
}
Field Type Description idstringUnique event identifier typestringEvent type (e.g., payment.succeeded, subscription.activated) orgIdstringOrganization the event belongs to timestampstringISO 8601 timestamp of when the event occurred dataobjectEvent-specific payload
Event types
Event Description payment.succeededA payment was successfully processed payment.failedA payment attempt failed invoice.createdA new invoice was generated subscription.activatedA subscriber’s service was activated subscription.suspendedA subscriber’s service was suspended (dunning) dunning.walled_gardenA subscriber was moved to walled garden due to non-payment
Retry policy
Failed deliveries (non-2xx response or timeout) are retried with exponential backoff:
Attempts : Up to 5 retries
Backoff : 30s, 2m, 10m, 1h, 6h
Timeout : 10 seconds per delivery attempt
Your endpoint should return a 2xx status code within 10 seconds to acknowledge receipt. Process
the event asynchronously if your handler needs more time.
Verifying webhooks
Webhook signature verification details will be published with the public API launch. Your
webhook endpoint should be served over HTTPS.