Download OpenAPI specification:
Contract-first OpenAPI spec for the ultra-api merchant surface.
All protected endpoints require a Bearer JWT token obtained from POST /api/v1/auth/login.
The token can be sent in:
Authorization: Bearer <token> headerauth_token HTTP-only cookieAdd X-App-Context: merchant header when operating in merchant context.
Admin users with this header are treated as the primary merchant actor.
All responses use the ApiResponse envelope:
{ "success": true|false, "data": ..., "error": "...", "meta": {...} }
Two modes are supported:
?page=1&per_page=20?pagination=cursor&cursor=<token>&limit=20Mutation endpoints that accept Idempotency-Key header will replay the cached
response on duplicate keys. The TTL is configurable per endpoint via the admin
runtime config (default: 24h). Expired keys are automatically purged by the
idempotency-cleanup background worker.
Authenticates a merchant or admin user. Returns a JWT token valid for
AUTH_COOKIE_TTL_SECONDS. Also sets an HTTP-only auth_token cookie.
Rate-limited to 10 requests per 60 seconds per IP.
| email required | string <email> |
| password | string >= 8 characters Required only if account has a password set |
{- "email": "[email protected]"
}{- "success": true,
- "data": {
- "token": "string",
- "expiresAt": 0,
- "userId": "string",
- "role": "admin",
- "isSuperAdmin": true,
- "merchantAppUserId": "string",
- "slaTier": "starter"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Returns the authenticated user's session info.
{- "success": true,
- "data": {
- "userId": "string",
- "role": "string",
- "email": "string",
- "name": "string",
- "isSuperAdmin": true,
- "merchantAppUserId": "string",
- "slaTier": "starter"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}{- "success": true,
- "data": {
- "loggedOut": true
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Initiates a mobile money payment via the specified provider.
Idempotency-Key header to safely retry.| Idempotency-Key | string Idempotency key for safe retries (TTL configurable per endpoint via admin config) |
| provider required | string (Provider) Enum: "mvola" "airtel" "orange" Mobile money provider |
| amount required | string^\d+(\.\d{1,2})?$ Numeric string (e.g. "10000") |
| description | string Optional payment description |
| customerPhone required | string Customer mobile money phone number |
object Arbitrary metadata attached to the payment |
{- "provider": "mvola",
- "amount": "10000",
- "customerPhone": "0340000000",
- "description": "Order #1234"
}{- "success": true,
- "data": {
- "id": "string",
- "provider": "mvola",
- "status": "pending",
- "amount": "string",
- "currency": "MGA",
- "feesAmount": "string",
- "feesCurrency": "string",
- "debitParty": "string",
- "creditParty": "string",
- "providerTransactionId": "string",
- "serverCorrelationId": "string",
- "correlationId": "string",
- "initiatedBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Lists payments for the authenticated user (or all payments for admins). Supports page and cursor pagination. Merchants see only their own payments.
| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| pagination | string Value: "cursor" Pass |
| cursor | string Opaque cursor token from previous cursor-paginated response |
| limit | integer [ 1 .. 100 ] Default: 20 Number of items per page (cursor mode) |
| status | string (PaymentStatus) Enum: "pending" "completed" "failed" "cancelled" "refunding" "refunded" "expired" |
| merchantId | string Filter by merchant ID (admin only) |
{- "success": true,
- "data": [
- {
- "id": "string",
- "provider": "mvola",
- "status": "pending",
- "amount": "string",
- "currency": "MGA",
- "feesAmount": "string",
- "feesCurrency": "string",
- "debitParty": "string",
- "creditParty": "string",
- "providerTransactionId": "string",
- "serverCorrelationId": "string",
- "correlationId": "string",
- "initiatedBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Streams a CSV file of payments. Requires admin or merchant role.
Admins must provide merchantId query param.
Requires Pro+ SLA tier.
| merchantId | string |
| status | string (PaymentStatus) Enum: "pending" "completed" "failed" "cancelled" "refunding" "refunded" "expired" |
| from | string <date-time> |
| to | string <date-time> |
{- "success": false,
- "error": "string"
}Returns refund support status and mode for each provider. Pass ?provider=mvola for a single provider.
| provider | string (Provider) Enum: "mvola" "airtel" "orange" Mobile money provider |
{- "success": true,
- "data": {
- "provider": "mvola",
- "supported": true,
- "mode": "simulation",
- "supportsPartial": true,
- "isAsync": true,
- "message": "string"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}{- "success": true,
- "data": {
- "refund": {
- "id": "string",
- "paymentId": "string",
- "provider": "mvola",
- "amount": "string",
- "currency": "string",
- "status": "pending",
- "mode": "simulation",
- "reason": "string",
- "failureCode": "string",
- "failureMessage": "string",
- "providerReference": "string",
- "attemptCount": 0,
- "requestedBy": "string",
- "processedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "payment": {
- "id": "string",
- "provider": "mvola",
- "status": "pending",
- "amount": "string",
- "currency": "MGA",
- "feesAmount": "string",
- "feesCurrency": "string",
- "debitParty": "string",
- "creditParty": "string",
- "providerTransactionId": "string",
- "serverCorrelationId": "string",
- "correlationId": "string",
- "initiatedBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z"
}
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| refundId required | string |
{- "success": true,
- "data": {
- "id": "string",
- "paymentId": "string",
- "provider": "mvola",
- "amount": "string",
- "currency": "string",
- "status": "pending",
- "mode": "simulation",
- "reason": "string",
- "failureCode": "string",
- "failureMessage": "string",
- "providerReference": "string",
- "attemptCount": 0,
- "requestedBy": "string",
- "processedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| refundId required | string |
| Idempotency-Key | string |
{- "success": true,
- "data": {
- "refund": {
- "id": "string",
- "paymentId": "string",
- "provider": "mvola",
- "amount": "string",
- "currency": "string",
- "status": "pending",
- "mode": "simulation",
- "reason": "string",
- "failureCode": "string",
- "failureMessage": "string",
- "providerReference": "string",
- "attemptCount": 0,
- "requestedBy": "string",
- "processedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "payment": {
- "id": "string",
- "provider": "mvola",
- "status": "pending",
- "amount": "string",
- "currency": "MGA",
- "feesAmount": "string",
- "feesCurrency": "string",
- "debitParty": "string",
- "creditParty": "string",
- "providerTransactionId": "string",
- "serverCorrelationId": "string",
- "correlationId": "string",
- "initiatedBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z"
}, - "capability": {
- "provider": "mvola",
- "supported": true,
- "mode": "simulation",
- "supportsPartial": true,
- "isAsync": true,
- "message": "string"
}
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}{- "success": true,
- "data": {
- "id": "string",
- "provider": "mvola",
- "status": "pending",
- "amount": "string",
- "currency": "MGA",
- "feesAmount": "string",
- "feesCurrency": "string",
- "debitParty": "string",
- "creditParty": "string",
- "providerTransactionId": "string",
- "serverCorrelationId": "string",
- "correlationId": "string",
- "initiatedBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Queries the provider for the latest payment status and updates the record. Dispatches webhooks on terminal transitions.
| id required | string |
{- "success": true,
- "data": {
- "id": "string",
- "provider": "mvola",
- "status": "pending",
- "amount": "string",
- "currency": "MGA",
- "feesAmount": "string",
- "feesCurrency": "string",
- "debitParty": "string",
- "creditParty": "string",
- "providerTransactionId": "string",
- "serverCorrelationId": "string",
- "correlationId": "string",
- "initiatedBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Creates a refund for a completed payment.
Idempotency-Key header.| id required | string |
| Idempotency-Key | string |
| amount | string^\d+(\.\d{1,2})?$ Refund amount (defaults to full payment amount) |
| reason | string [ 3 .. 255 ] characters |
{- "amount": "string",
- "reason": "string"
}{- "success": true,
- "data": {
- "refund": {
- "id": "string",
- "paymentId": "string",
- "provider": "mvola",
- "amount": "string",
- "currency": "string",
- "status": "pending",
- "mode": "simulation",
- "reason": "string",
- "failureCode": "string",
- "failureMessage": "string",
- "providerReference": "string",
- "attemptCount": 0,
- "requestedBy": "string",
- "processedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "payment": {
- "id": "string",
- "provider": "mvola",
- "status": "pending",
- "amount": "string",
- "currency": "MGA",
- "feesAmount": "string",
- "feesCurrency": "string",
- "debitParty": "string",
- "creditParty": "string",
- "providerTransactionId": "string",
- "serverCorrelationId": "string",
- "correlationId": "string",
- "initiatedBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z",
- "expiresAt": "2019-08-24T14:15:22Z"
}, - "capability": {
- "provider": "mvola",
- "supported": true,
- "mode": "simulation",
- "supportsPartial": true,
- "isAsync": true,
- "message": "string"
}
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| id required | string |
| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
{- "success": true,
- "data": [
- {
- "id": "string",
- "paymentId": "string",
- "provider": "mvola",
- "amount": "string",
- "currency": "string",
- "status": "pending",
- "mode": "simulation",
- "reason": "string",
- "failureCode": "string",
- "failureMessage": "string",
- "providerReference": "string",
- "attemptCount": 0,
- "requestedBy": "string",
- "processedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
{- "success": true,
- "data": [
- {
- "id": "string",
- "token": "string",
- "title": "string",
- "amount": "string",
- "currency": "MGA",
- "status": "active",
- "maxUses": 0,
- "useCount": 0,
- "expiresAt": "2019-08-24T14:15:22Z",
- "providers": "string",
- "metadata": "string",
- "createdBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| title required | string [ 1 .. 255 ] characters |
| amount required | string^\d+(\.\d{1,2})?$ |
| currency | string Default: "MGA" |
| maxUses | integer or null |
| expiresAt | string or null <date-time> |
Array of Provider (strings) or null | |
object |
{- "title": "string",
- "amount": "string",
- "currency": "MGA",
- "maxUses": 0,
- "expiresAt": "2019-08-24T14:15:22Z",
- "providers": [
- "mvola"
], - "metadata": { }
}{- "success": true,
- "data": {
- "id": "string",
- "token": "string",
- "title": "string",
- "amount": "string",
- "currency": "MGA",
- "status": "active",
- "maxUses": 0,
- "useCount": 0,
- "expiresAt": "2019-08-24T14:15:22Z",
- "providers": "string",
- "metadata": "string",
- "createdBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}{- "success": true,
- "data": {
- "id": "string",
- "token": "string",
- "title": "string",
- "amount": "string",
- "currency": "MGA",
- "status": "active",
- "maxUses": 0,
- "useCount": 0,
- "expiresAt": "2019-08-24T14:15:22Z",
- "providers": "string",
- "metadata": "string",
- "createdBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| id required | string |
| title | string |
| status | string (PaymentLinkStatus) Enum: "active" "depleted" "expired" "disabled" |
| amount | string^\d+(\.\d{1,2})?$ |
| maxUses | integer or null |
| expiresAt | string or null <date-time> |
{- "title": "string",
- "status": "active",
- "amount": "string",
- "maxUses": 0,
- "expiresAt": "2019-08-24T14:15:22Z"
}{- "success": true,
- "data": {
- "id": "string",
- "token": "string",
- "title": "string",
- "amount": "string",
- "currency": "MGA",
- "status": "active",
- "maxUses": 0,
- "useCount": 0,
- "expiresAt": "2019-08-24T14:15:22Z",
- "providers": "string",
- "metadata": "string",
- "createdBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}{- "success": true,
- "data": {
- "id": "string"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| pagination | string Value: "cursor" Pass |
| cursor | string Opaque cursor token from previous cursor-paginated response |
| limit | integer [ 1 .. 100 ] Default: 20 Number of items per page (cursor mode) |
| due | string Value: "today" Filter subscriptions due today |
| userId | string Filter by merchant user ID (admin only) |
{- "success": true,
- "data": [
- {
- "id": "string",
- "label": "string",
- "customerPhone": "string",
- "amount": "string",
- "currency": "MGA",
- "description": "string",
- "interval": "daily",
- "provider": "mvola",
- "status": "active",
- "nextRenewalAt": "2019-08-24T14:15:22Z",
- "renewalLockToken": "string",
- "lastPaymentId": "string",
- "createdBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| label required | string [ 1 .. 255 ] characters |
| customerPhone required | string [ 10 .. 30 ] characters |
| amount required | string^\d+(\.\d{1,2})?$ |
| currency | string <= 10 characters Default: "MGA" |
| description | string <= 500 characters |
| interval required | string (SubscriptionInterval) Enum: "daily" "weekly" "monthly" "quarterly" "annual" |
| provider | string (Provider) Default: "mvola" Enum: "mvola" "airtel" "orange" Mobile money provider |
| nextRenewalAt required | string <date-time> |
object |
{- "label": "string",
- "customerPhone": "stringstri",
- "amount": "string",
- "currency": "MGA",
- "description": "string",
- "interval": "daily",
- "provider": "mvola",
- "nextRenewalAt": "2019-08-24T14:15:22Z",
- "metadata": { }
}{- "success": true,
- "data": {
- "id": "string",
- "label": "string",
- "customerPhone": "string",
- "amount": "string",
- "currency": "MGA",
- "description": "string",
- "interval": "daily",
- "provider": "mvola",
- "status": "active",
- "nextRenewalAt": "2019-08-24T14:15:22Z",
- "renewalLockToken": "string",
- "lastPaymentId": "string",
- "createdBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| merchantId | string |
| status | string (SubscriptionStatus) Enum: "active" "paused" "cancelled" |
| overdue | string Enum: "true" "false" |
| from | string <date-time> |
| to | string <date-time> |
{- "success": false,
- "error": "string"
}{- "success": true,
- "data": {
- "id": "string",
- "label": "string",
- "customerPhone": "string",
- "amount": "string",
- "currency": "MGA",
- "description": "string",
- "interval": "daily",
- "provider": "mvola",
- "status": "active",
- "nextRenewalAt": "2019-08-24T14:15:22Z",
- "renewalLockToken": "string",
- "lastPaymentId": "string",
- "createdBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| id required | string |
| label | string [ 1 .. 255 ] characters |
| status | string Enum: "active" "paused" "cancelled" |
| amount | string^\d+(\.\d{1,2})?$ |
| interval | string (SubscriptionInterval) Enum: "daily" "weekly" "monthly" "quarterly" "annual" |
| provider | string (Provider) Enum: "mvola" "airtel" "orange" Mobile money provider |
| nextRenewalAt | string <date-time> |
{- "label": "string",
- "status": "active",
- "amount": "string",
- "interval": "daily",
- "provider": "mvola",
- "nextRenewalAt": "2019-08-24T14:15:22Z"
}{- "success": true,
- "data": {
- "id": "string",
- "label": "string",
- "customerPhone": "string",
- "amount": "string",
- "currency": "MGA",
- "description": "string",
- "interval": "daily",
- "provider": "mvola",
- "status": "active",
- "nextRenewalAt": "2019-08-24T14:15:22Z",
- "renewalLockToken": "string",
- "lastPaymentId": "string",
- "createdBy": "string",
- "metadata": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}{- "success": true,
- "data": {
- "id": "string"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Manually initiates a renewal payment for the subscription.
Idempotent with Idempotency-Key header.
| id required | string |
| Idempotency-Key | string |
{- "success": true,
- "data": { },
- "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| userId | string Filter by owner (admin only) |
{- "success": true,
- "data": [
- {
- "id": "string",
- "secret": "string",
- "events": "string",
- "isActive": true,
- "createdBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| url required | string <uri> |
| secret required | string >= 16 characters HMAC signing secret (min 16 chars) |
| events required | Array of strings (WebhookEvent) non-empty Items Enum: "payment.completed" "payment.failed" "payment.refunded" "subscription.renewed" "payment_link.paid" |
| isActive | boolean Default: true |
{- "secret": "stringstringstri",
- "events": [
- "payment.completed"
], - "isActive": true
}{- "success": true,
- "data": {
- "id": "string",
- "secret": "string",
- "events": "string",
- "isActive": true,
- "createdBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| id required | string |
| url | string <uri> |
| secret | string >= 16 characters |
| events | Array of strings (WebhookEvent) non-empty Items Enum: "payment.completed" "payment.failed" "payment.refunded" "subscription.renewed" "payment_link.paid" |
| isActive | boolean |
{- "secret": "stringstringstri",
- "events": [
- "payment.completed"
], - "isActive": true
}{- "success": true,
- "data": {
- "id": "string",
- "secret": "string",
- "events": "string",
- "isActive": true,
- "createdBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}{- "success": true,
- "data": {
- "id": "string"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| pagination | string Value: "cursor" Pass |
| cursor | string Opaque cursor token from previous cursor-paginated response |
| limit | integer [ 1 .. 100 ] Default: 20 Number of items per page (cursor mode) |
| endpointId | string |
| event | string (WebhookEvent) Enum: "payment.completed" "payment.failed" "payment.refunded" "subscription.renewed" "payment_link.paid" |
| success | string Enum: "true" "false" |
| dlq | string Enum: "true" "false" Filter dead-lettered deliveries |
{- "success": true,
- "data": [
- {
- "id": "string",
- "endpointId": "string",
- "event": "payment.completed",
- "payload": "string",
- "responseStatus": 0,
- "responseBody": "string",
- "success": true,
- "durationMs": 0,
- "retryCount": 0,
- "nextRetryAt": "2019-08-24T14:15:22Z",
- "lastError": "string",
- "deadLetteredAt": "2019-08-24T14:15:22Z",
- "endpointCreatedBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Creates a new delivery attempt for the given delivery.
| id required | string |
{- "success": true,
- "data": {
- "id": "string",
- "endpointId": "string",
- "event": "payment.completed",
- "payload": "string",
- "responseStatus": 0,
- "responseBody": "string",
- "success": true,
- "durationMs": 0,
- "retryCount": 0,
- "nextRetryAt": "2019-08-24T14:15:22Z",
- "lastError": "string",
- "deadLetteredAt": "2019-08-24T14:15:22Z",
- "endpointCreatedBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Returns deliveries that have been dead-lettered (exhausted all retries).
| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| pagination | string Value: "cursor" Pass |
| cursor | string Opaque cursor token from previous cursor-paginated response |
| limit | integer [ 1 .. 100 ] Default: 20 Number of items per page (cursor mode) |
| endpointId | string |
| event | string (WebhookEvent) Enum: "payment.completed" "payment.failed" "payment.refunded" "subscription.renewed" "payment_link.paid" |
{- "success": true,
- "data": [
- {
- "id": "string",
- "endpointId": "string",
- "event": "payment.completed",
- "payload": "string",
- "responseStatus": 0,
- "responseBody": "string",
- "success": true,
- "durationMs": 0,
- "retryCount": 0,
- "nextRetryAt": "2019-08-24T14:15:22Z",
- "lastError": "string",
- "deadLetteredAt": "2019-08-24T14:15:22Z",
- "endpointCreatedBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Re-dispatches a dead-lettered delivery. The original delivery is marked replayed and a new delivery is created. Admin only.
| id required | string |
{- "success": true,
- "data": {
- "id": "string",
- "endpointId": "string",
- "event": "payment.completed",
- "payload": "string",
- "responseStatus": 0,
- "responseBody": "string",
- "success": true,
- "durationMs": 0,
- "retryCount": 0,
- "nextRetryAt": "2019-08-24T14:15:22Z",
- "lastError": "string",
- "deadLetteredAt": "2019-08-24T14:15:22Z",
- "endpointCreatedBy": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Replays multiple dead-lettered deliveries at once. Supports dry-run mode. Admin only, requires Pro+ tier minimum.
| ids required | Array of strings [ 1 .. 100 ] items |
| dryRun | boolean Default: false |
{- "ids": [
- "del_abc123",
- "del_def456"
], - "dryRun": false
}{- "success": true,
- "data": {
- "requested": 0,
- "processed": 0,
- "replayed": 0,
- "dryRun": true,
- "skipped": {
- "notFound": [
- "string"
], - "notDlq": [
- "string"
], - "notEligibleSla": [
- "string"
], - "unauthorized": [
- "string"
]
}, - "failed": [
- {
- "id": "string",
- "error": "string"
}
], - "createdDeliveryIds": [
- "string"
]
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Returns the calling merchant's configured providers (credentials are masked).
{- "success": true,
- "data": [
- { }
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| name required | string (Provider) Enum: "mvola" "airtel" "orange" Mobile money provider |
{- "success": true,
- "data": { },
- "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Upserts provider credentials. The client_secret / consumer_secret
fields are encrypted at rest and never returned in GET responses.
| name required | string (Provider) Enum: "mvola" "airtel" "orange" Mobile money provider |
Provider-specific config (see MvolaProviderConfig, AirtelProviderConfig, OrangeProviderConfig)
{ }{- "success": true,
- "data": { },
- "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| name required | string (Provider) Enum: "mvola" "airtel" "orange" Mobile money provider |
{- "success": true,
- "data": {
- "provider": "string"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Returns aggregated payment, subscription, and payment link stats. Accessible to merchants and admins.
| period | string (AnalyticsPeriod) Default: "month" Enum: "day" "week" "month" |
| from | string <date> |
| to | string <date> |
{- "success": true,
- "data": { },
- "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| period | string (AnalyticsPeriod) Default: "month" Enum: "day" "week" "month" |
| from | string <date> |
| to | string <date> |
{- "success": true,
- "data": { },
- "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| period | string (AnalyticsPeriod) Default: "month" Enum: "day" "week" "month" |
| from | string <date> |
| to | string <date> |
{- "success": true,
- "data": { },
- "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| period | string (AnalyticsPeriod) Default: "month" Enum: "day" "week" "month" |
| from | string <date> |
| to | string <date> |
{- "success": true,
- "data": {
- "period": "string",
- "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z",
- "days": [
- { }
], - "summary": { }
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Returns the current state of the 4-step Pro+ onboarding wizard for the authenticated merchant. Steps are derived from live data (no separate state table) and are automatically marked completed when the underlying data is present.
Steps:
{- "success": true,
- "data": {
- "steps": {
- "providerCredentials": {
- "completed": true
}, - "webhookEndpoint": {
- "completed": true
}, - "firstPaymentLink": {
- "completed": true
}, - "uat": {
- "completed": true,
- "ready": true,
- "signals": {
- "completedPayments": 0,
- "failedPayments": 0,
- "webhookDeliveriesSucceeded": 0,
- "expiredLinks": 0,
- "depletedLinks": 0
}
}
}, - "overallCompleted": true
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Validates that UAT prerequisites are met and records a permanent
onboarding.uat.confirmed audit entry. Idempotent — returns
alreadyConfirmed: true if called more than once.
Prerequisites (enforced server-side):
Returns 409 if any prerequisite is missing.
{- "success": true,
- "data": {
- "steps": {
- "providerCredentials": {
- "completed": true
}, - "webhookEndpoint": {
- "completed": true
}, - "firstPaymentLink": {
- "completed": true
}, - "uat": {
- "completed": true,
- "ready": true,
- "signals": {
- "completedPayments": 0,
- "failedPayments": 0,
- "webhookDeliveriesSucceeded": 0,
- "expiredLinks": 0,
- "depletedLinks": 0
}
}
}, - "overallCompleted": true,
- "alreadyConfirmed": true
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Returns the payment link title, amount, currency, and available providers. No auth required.
| token required | string |
{- "success": true,
- "data": {
- "title": "string",
- "amount": "string",
- "currency": "string",
- "description": "string",
- "providers": [
- "mvola"
]
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Initiates a mobile money payment through a public link. Rate-limited to 20 req/60s per IP.
Supports idempotency via Idempotency-Key header.
| token required | string |
| Idempotency-Key | string |
| customerPhone required | string [ 10 .. 30 ] characters |
| provider | string (Provider) Enum: "mvola" "airtel" "orange" Mobile money provider |
{- "customerPhone": "0340000000",
- "provider": "mvola"
}{- "success": true,
- "data": {
- "paymentId": "string",
- "serverCorrelationId": "string"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Fire-and-forget endpoint for frontend checkout error telemetry. Rate-limited to 30 req/60s per IP. No auth required.
| eventType required | string Value: "checkout.payment.error" |
| category required | string Enum: "payment_failed" "payment_timeout" "network_error" |
| phase required | string Enum: "link_load" "payment_initiate" "payment_poll" |
| provider | string Enum: "mvola" "airtel" "orange" "unknown" |
| paymentId | string <= 50 characters |
| checkoutToken | string <= 200 characters |
| attemptId required | string [ 1 .. 100 ] characters |
| requestId | string <= 100 characters |
| httpStatus | integer [ 0 .. 599 ] |
| pollCount | integer [ 0 .. 1000 ] |
| maxPolls | integer [ 0 .. 1000 ] |
| uiState | string <= 50 characters |
| message | string <= 500 characters |
| occurredAt | string <date-time> |
object |
{- "eventType": "checkout.payment.error",
- "category": "payment_failed",
- "phase": "link_load",
- "provider": "mvola",
- "paymentId": "string",
- "checkoutToken": "string",
- "attemptId": "string",
- "requestId": "string",
- "httpStatus": 599,
- "pollCount": 1000,
- "maxPolls": 1000,
- "uiState": "string",
- "message": "string",
- "occurredAt": "2019-08-24T14:15:22Z",
- "client": {
- "online": true,
- "userAgent": "string",
- "effectiveType": "string"
}
}{- "success": true,
- "data": {
- "received": true
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Returns the current payment status. If still pending, checks the provider. Rate-limited to 30 req/60s per IP. No auth required.
| paymentId required | string |
{- "success": true,
- "data": {
- "status": "pending"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Authenticates an admin user. Returns a JWT and sets an HTTP-only cookie. Rate-limited to 10 req/60s per IP.
| email required | string <email> |
| password | string >= 8 characters |
{- "password": "stringst"
}{- "success": true,
- "data": {
- "token": "string",
- "expiresAt": 0,
- "userId": "string",
- "isSuperAdmin": true
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| userId required | string non-empty |
| name | string [ 1 .. 100 ] characters |
| ttl | integer >= 1 |
| customClaims | object |
{- "userId": "string",
- "name": "string",
- "ttl": 1,
- "customClaims": { }
}{- "success": true,
- "data": {
- "id": "string",
- "token": "string",
- "name": "string",
- "userId": "string",
- "expiresAt": 0,
- "customClaims": { }
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| userId | string |
| status | string Enum: "active" "revoked" "expired" |
{- "success": true,
- "data": [
- {
- "id": "string",
- "userId": "string",
- "name": "string",
- "expiresAt": 0,
- "revokedAt": 0,
- "createdBy": "string",
- "customTtl": 0,
- "customClaims": { },
- "createdAt": "2019-08-24T14:15:22Z",
- "status": "active"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}{- "success": true,
- "data": {
- "id": "string",
- "userId": "string",
- "name": "string",
- "expiresAt": 0,
- "revokedAt": 0,
- "createdBy": "string",
- "customTtl": 0,
- "customClaims": { },
- "createdAt": "2019-08-24T14:15:22Z",
- "status": "active"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}{- "success": true,
- "data": {
- "revoked": true,
- "alreadyRevoked": true
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| search | string Search name or email |
| role | string Enum: "admin" "user" "customer" |
{- "success": true,
- "data": [
- {
- "id": "string",
- "email": "string",
- "name": "string",
- "role": "admin",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tokenCount": 0
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| email required | string <email> |
| name required | string [ 1 .. 100 ] characters |
| role | string Enum: "admin" "user" "customer" |
| password | string >= 8 characters |
{- "name": "string",
- "role": "admin",
- "password": "stringst"
}{- "success": true,
- "data": {
- "id": "string",
- "email": "string",
- "name": "string",
- "role": "admin",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tokenCount": 0
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| id required | string |
| name | string [ 1 .. 100 ] characters |
string <email> | |
| role | string Enum: "admin" "user" "customer" |
{- "name": "string",
- "role": "admin"
}{- "success": true,
- "data": {
- "id": "string",
- "email": "string",
- "name": "string",
- "role": "admin",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "tokenCount": 0
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Cannot delete a user with payment history (returns 409).
| id required | string |
{- "success": true,
- "data": {
- "deleted": true,
- "id": "string"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Super-admin only. Returns all runtime configuration values.
{- "success": true,
- "data": { },
- "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Super-admin only. Partial update of runtime config values.
Partial config update (see updateConfigSchema for all fields)
{ }{- "success": true,
- "data": { },
- "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| action | string Filter by action (e.g. payment.completed) |
| entityType | string Filter by entity type (e.g. payment) |
| userId | string Filter by user ID |
{- "success": true,
- "data": [
- {
- "id": "string",
- "action": "string",
- "entityType": "string",
- "entityId": "string",
- "userId": "string",
- "ipAddress": "string",
- "metadata": { },
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Streams audit logs as a CSV file. Supports date range and field filters.
| action | string |
| entityType | string |
| userId | string |
| from | string <date-time> |
| to | string <date-time> |
{- "success": false,
- "error": "string"
}{- "success": true,
- "data": [
- {
- "provider": "mvola",
- "enabled": true,
- "config": { },
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| name required | string (Provider) Enum: "mvola" "airtel" "orange" Mobile money provider |
| userId | string Get user-specific config instead of global |
{- "success": true,
- "data": {
- "provider": "mvola",
- "enabled": true,
- "config": { },
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Upserts global provider credentials. Secrets are encrypted at rest. Masked values (****) in the request preserve existing values.
| name required | string (Provider) Enum: "mvola" "airtel" "orange" Mobile money provider |
Provider-specific config (MvolaProviderConfig, AirtelProviderConfig, OrangeProviderConfig)
{ }{- "success": true,
- "data": {
- "provider": "string",
- "enabled": true,
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| name required | string (Provider) Enum: "mvola" "airtel" "orange" Mobile money provider |
{- "success": true,
- "data": {
- "deleted": true
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Returns the SLA tier list, feature flags, and per-tier rate limits.
{- "success": true,
- "data": {
- "tiers": [
- "string"
], - "flags": { },
- "rateLimits": { }
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| platform | string (SocialPlatform) Enum: "meta" "tiktok" |
{- "success": true,
- "data": [
- {
- "id": "string",
- "platform": "meta",
- "platformAccountId": "string",
- "platformAccountName": "string",
- "status": "active",
- "scopes": [
- "string"
], - "connectedAt": "2019-08-24T14:15:22Z",
- "tokenExpiresAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Returns the OAuth authorization URL to redirect the user to.
| platform required | string (SocialPlatform) Enum: "meta" "tiktok" |
| redirectUri required | string <uri> |
{- "platform": "meta",
}{- "success": true,
- "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Handles the OAuth redirect from the social platform. Redirects to frontend with status.
| platform required | string (SocialPlatform) Enum: "meta" "tiktok" |
| code required | string |
| state required | string |
{- "success": false,
- "error": "string"
}{- "success": true,
- "data": {
- "deleted": true,
- "id": "string"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| id required | string |
{- "success": true,
- "data": {
- "refreshed": true,
- "id": "string"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| status | string (SocialPostStatus) Enum: "draft" "scheduled" "publishing" "published" "failed" |
| platform | string (SocialPlatform) Enum: "meta" "tiktok" |
| socialAccountId | string |
{- "success": true,
- "data": [
- {
- "id": "string",
- "userId": "string",
- "socialAccountId": "string",
- "platform": "meta",
- "content": "string",
- "mediaUrls": [
- "string"
], - "status": "draft",
- "scheduledAt": "2019-08-24T14:15:22Z",
- "publishedAt": "2019-08-24T14:15:22Z",
- "platformPostId": "string",
- "errorMessage": "string",
- "retryCount": 0,
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Creates a draft or scheduled post. If scheduledAt is provided, status is set to scheduled.
| socialAccountId required | string non-empty |
| content required | string [ 1 .. 2200 ] characters |
| mediaUrls | Array of strings <uri> <= 10 items [ items <uri > ] |
| scheduledAt | string <date-time> |
{- "socialAccountId": "string",
- "content": "string",
- "scheduledAt": "2019-08-24T14:15:22Z"
}{- "success": true,
- "data": {
- "id": "string",
- "userId": "string",
- "socialAccountId": "string",
- "platform": "meta",
- "content": "string",
- "mediaUrls": [
- "string"
], - "status": "draft",
- "scheduledAt": "2019-08-24T14:15:22Z",
- "publishedAt": "2019-08-24T14:15:22Z",
- "platformPostId": "string",
- "errorMessage": "string",
- "retryCount": 0,
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}{- "success": true,
- "data": {
- "id": "string",
- "userId": "string",
- "socialAccountId": "string",
- "platform": "meta",
- "content": "string",
- "mediaUrls": [
- "string"
], - "status": "draft",
- "scheduledAt": "2019-08-24T14:15:22Z",
- "publishedAt": "2019-08-24T14:15:22Z",
- "platformPostId": "string",
- "errorMessage": "string",
- "retryCount": 0,
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "publishLogs": [
- {
- "id": "string",
- "socialPostId": "string",
- "socialAccountId": "string",
- "action": "publish",
- "status": "success",
- "platformResponse": { },
- "errorDetails": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}
]
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Only draft or scheduled posts can be updated.
| id required | string |
| content | string [ 1 .. 2200 ] characters |
| mediaUrls | Array of strings <uri> <= 10 items [ items <uri > ] |
| scheduledAt | string <date-time> |
{- "content": "string",
- "scheduledAt": "2019-08-24T14:15:22Z"
}{- "success": true,
- "data": {
- "id": "string",
- "userId": "string",
- "socialAccountId": "string",
- "platform": "meta",
- "content": "string",
- "mediaUrls": [
- "string"
], - "status": "draft",
- "scheduledAt": "2019-08-24T14:15:22Z",
- "publishedAt": "2019-08-24T14:15:22Z",
- "platformPostId": "string",
- "errorMessage": "string",
- "retryCount": 0,
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Only draft or scheduled posts can be deleted.
| id required | string |
{- "success": true,
- "data": {
- "deleted": true,
- "id": "string"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Only draft or scheduled posts can be published.
| id required | string |
{- "success": true,
- "data": {
- "id": "string",
- "userId": "string",
- "socialAccountId": "string",
- "platform": "meta",
- "content": "string",
- "mediaUrls": [
- "string"
], - "status": "draft",
- "scheduledAt": "2019-08-24T14:15:22Z",
- "publishedAt": "2019-08-24T14:15:22Z",
- "platformPostId": "string",
- "errorMessage": "string",
- "retryCount": 0,
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Reverts a scheduled post back to draft status.
| id required | string |
{- "success": true,
- "data": {
- "id": "string",
- "userId": "string",
- "socialAccountId": "string",
- "platform": "meta",
- "content": "string",
- "mediaUrls": [
- "string"
], - "status": "draft",
- "scheduledAt": "2019-08-24T14:15:22Z",
- "publishedAt": "2019-08-24T14:15:22Z",
- "platformPostId": "string",
- "errorMessage": "string",
- "retryCount": 0,
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Super-admin only. Lists all social accounts across all users.
| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| platform | string (SocialPlatform) Enum: "meta" "tiktok" |
| userId | string |
| status | string (SocialAccountStatus) Enum: "active" "revoked" "expired" |
{- "success": true,
- "data": [
- {
- "id": "string",
- "platform": "meta",
- "platformAccountId": "string",
- "platformAccountName": "string",
- "status": "active",
- "scopes": [
- "string"
], - "connectedAt": "2019-08-24T14:15:22Z",
- "tokenExpiresAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Super-admin only. Can activate or revoke accounts.
| id required | string |
| status required | string Enum: "active" "revoked" |
{- "status": "active"
}{- "success": true,
- "data": {
- "id": "string",
- "platform": "meta",
- "platformAccountId": "string",
- "platformAccountName": "string",
- "status": "active",
- "scopes": [
- "string"
], - "connectedAt": "2019-08-24T14:15:22Z",
- "tokenExpiresAt": "2019-08-24T14:15:22Z"
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Super-admin only. Lists all social posts across all users.
| page | integer >= 1 Default: 1 |
| per_page | integer [ 1 .. 100 ] Default: 20 |
| status | string (SocialPostStatus) Enum: "draft" "scheduled" "publishing" "published" "failed" |
| platform | string (SocialPlatform) Enum: "meta" "tiktok" |
| userId | string |
{- "success": true,
- "data": [
- {
- "id": "string",
- "userId": "string",
- "socialAccountId": "string",
- "platform": "meta",
- "content": "string",
- "mediaUrls": [
- "string"
], - "status": "draft",
- "scheduledAt": "2019-08-24T14:15:22Z",
- "publishedAt": "2019-08-24T14:15:22Z",
- "platformPostId": "string",
- "errorMessage": "string",
- "retryCount": 0,
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Super-admin only. Returns all publish/cancel attempts for a post.
| id required | string |
{- "success": true,
- "data": [
- {
- "id": "string",
- "socialPostId": "string",
- "socialAccountId": "string",
- "action": "publish",
- "status": "success",
- "platformResponse": { },
- "errorDetails": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}Super-admin only. Returns aggregated stats across all social accounts and posts.
{- "success": true,
- "data": {
- "accountsByPlatform": {
- "property1": 0,
- "property2": 0
}, - "postsByStatus": {
- "property1": 0,
- "property2": 0
}, - "publishSuccessRate": 0,
- "totalPublishAttempts": 0
}, - "error": "string",
- "meta": {
- "mode": "page",
- "page": 0,
- "perPage": 0,
- "total": 0,
- "totalPages": 0,
- "limit": 0,
- "nextCursor": "string",
- "hasNext": true
}
}