Skip to main content

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
EnvironmentPattern
Productionhttps://{orgSlug}.api.fyberpay.com
Platform adminhttps://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.
After a successful login, the server sets two httpOnly cookies:
CookiePurposeLifetime
access_tokenJWT for request authentication15 minutes
refresh_tokenOpaque token for obtaining new access tokens7 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.
ScopeLimit
Authenticated requests300 requests per minute per user
Login / OTP endpoints10 requests per minute per IP
Webhook callbacks100 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.

Error Response Format

All errors follow a consistent JSON structure:
{
  "statusCode": 422,
  "message": "Validation failed: email must be a valid email address",
  "error": "Unprocessable Entity"
}
FieldTypeDescription
statusCodenumberHTTP status code
messagestring or string[]Human-readable error description. Validation errors may return an array of messages.
errorstringHTTP status text

Common status codes

CodeMeaning
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.

Pagination

List endpoints use cursor-based pagination for consistent, performant results.

Request parameters

ParameterTypeDefaultDescription
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
}
FieldTypeDescription
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

  1. Generate a unique key (a UUID v4 works well) and include it in the Idempotency-Key header.
  2. The server processes the request and caches the response for 24 hours.
  3. 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

ScenarioResult
First request with a new keyProcessed normally; response cached
Repeat request with a completed keyCached response returned (no re-processing)
Repeat request while original is still processing409 Conflict returned
Request fails with an errorKey is cleared so you can safely retry
No Idempotency-Key header providedRequest 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.

Delivery format

{
  "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"
  }
}
FieldTypeDescription
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

EventDescription
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.