ultra-api Merchant API (1.0.0)

Download OpenAPI specification:

License: MIT

Contract-first OpenAPI spec for the ultra-api merchant surface.

Authentication

All protected endpoints require a Bearer JWT token obtained from POST /api/v1/auth/login. The token can be sent in:

  • Authorization: Bearer <token> header
  • auth_token HTTP-only cookie

Merchant Scope

Add X-App-Context: merchant header when operating in merchant context. Admin users with this header are treated as the primary merchant actor.

Response Envelope

All responses use the ApiResponse envelope:

{ "success": true|false, "data": ..., "error": "...", "meta": {...} }

Pagination

Two modes are supported:

  • Page mode (default): ?page=1&per_page=20
  • Cursor mode: ?pagination=cursor&cursor=<token>&limit=20

Idempotency

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

auth

Authentication (login, session, logout)

Login (merchant or admin)

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.

Request Body schema: application/json
required
email
required
string <email>
password
string >= 8 characters

Required only if account has a password set

Responses

Request samples

Content type
application/json
Example
{
  • "email": "merchant@example.com"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Get current session

Returns the authenticated user's session info.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Logout

Revokes the current token and clears the auth cookie.

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

payments

Payment initiation, polling, refunds, CSV export

Initiate a payment

Initiates a mobile money payment via the specified provider.

  • Idempotent: provide Idempotency-Key header to safely retry.
  • Rate-limited to 30 requests per 60 seconds per user.
  • Merchants see only their own payments.
Authorizations:
bearerAuth
header Parameters
Idempotency-Key
string

Idempotency key for safe retries (TTL configurable per endpoint via admin config)

Request Body schema: application/json
required
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

Responses

Request samples

Content type
application/json
{
  • "provider": "mvola",
  • "amount": "10000",
  • "customerPhone": "0340000000",
  • "description": "Order #1234"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

List payments

Lists payments for the authenticated user (or all payments for admins). Supports page and cursor pagination. Merchants see only their own payments.

Authorizations:
bearerAuth
query Parameters
page
integer >= 1
Default: 1
per_page
integer [ 1 .. 100 ]
Default: 20
pagination
string
Value: "cursor"

Pass cursor to switch to cursor-based pagination

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)

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Export payments as CSV

Streams a CSV file of payments. Requires admin or merchant role. Admins must provide merchantId query param. Requires Pro+ SLA tier.

Authorizations:
bearerAuth
query Parameters
merchantId
string
status
string (PaymentStatus)
Enum: "pending" "completed" "failed" "cancelled" "refunding" "refunded" "expired"
from
string <date-time>
to
string <date-time>

Responses

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "string"
}

List refund capabilities by provider

Returns refund support status and mode for each provider. Pass ?provider=mvola for a single provider.

Authorizations:
bearerAuth
query Parameters
provider
string (Provider)
Enum: "mvola" "airtel" "orange"

Mobile money provider

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Get a refund by ID

Authorizations:
bearerAuth
path Parameters
refundId
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Poll refund status from provider

Authorizations:
bearerAuth
path Parameters
refundId
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Retry a failed or cancelled refund

Authorizations:
bearerAuth
path Parameters
refundId
required
string
header Parameters
Idempotency-Key
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Get a payment by ID

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Poll payment status from provider

Queries the provider for the latest payment status and updates the record. Dispatches webhooks on terminal transitions.

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Create a refund request for a payment

Creates a refund for a completed payment.

  • In simulation mode, the refund is finalized immediately.
  • In live mode, the refund is sent to the provider. Idempotent with Idempotency-Key header.
Authorizations:
bearerAuth
path Parameters
id
required
string
header Parameters
Idempotency-Key
string
Request Body schema: application/json
optional
amount
string^\d+(\.\d{1,2})?$

Refund amount (defaults to full payment amount)

reason
string [ 3 .. 255 ] characters

Responses

Request samples

Content type
application/json
{
  • "amount": "string",
  • "reason": "string"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

List refunds for a payment

Authorizations:
bearerAuth
path Parameters
id
required
string
query Parameters
page
integer >= 1
Default: 1
per_page
integer [ 1 .. 100 ]
Default: 20

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Create a payment link

Authorizations:
bearerAuth
Request Body schema: application/json
required
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

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "amount": "string",
  • "currency": "MGA",
  • "maxUses": 0,
  • "expiresAt": "2019-08-24T14:15:22Z",
  • "providers": [
    ],
  • "metadata": { }
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Get a payment link by ID

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Update a payment link

Authorizations:
bearerAuth
path Parameters
id
required
string
Request Body schema: application/json
required
non-empty
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>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "status": "active",
  • "amount": "string",
  • "maxUses": 0,
  • "expiresAt": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Delete a payment link

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

subscriptions

Recurring subscription management

List subscriptions

Authorizations:
bearerAuth
query Parameters
page
integer >= 1
Default: 1
per_page
integer [ 1 .. 100 ]
Default: 20
pagination
string
Value: "cursor"

Pass cursor to switch to cursor-based pagination

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)

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Create a subscription

Authorizations:
bearerAuth
Request Body schema: application/json
required
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

Responses

Request samples

Content type
application/json
{
  • "label": "string",
  • "customerPhone": "stringstri",
  • "amount": "string",
  • "currency": "MGA",
  • "description": "string",
  • "interval": "daily",
  • "provider": "mvola",
  • "nextRenewalAt": "2019-08-24T14:15:22Z",
  • "metadata": { }
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Export subscriptions as CSV

Authorizations:
bearerAuth
query Parameters
merchantId
string
status
string (SubscriptionStatus)
Enum: "active" "paused" "cancelled"
overdue
string
Enum: "true" "false"
from
string <date-time>
to
string <date-time>

Responses

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "string"
}

Get a subscription by ID

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Update a subscription

Authorizations:
bearerAuth
path Parameters
id
required
string
Request Body schema: application/json
required
non-empty
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>

Responses

Request samples

Content type
application/json
{
  • "label": "string",
  • "status": "active",
  • "amount": "string",
  • "interval": "daily",
  • "provider": "mvola",
  • "nextRenewalAt": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Delete a subscription

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Manually trigger a subscription renewal

Manually initiates a renewal payment for the subscription. Idempotent with Idempotency-Key header.

Authorizations:
bearerAuth
path Parameters
id
required
string
header Parameters
Idempotency-Key
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": { },
  • "error": "string",
  • "meta": {
    }
}

webhooks

Webhook endpoint registration, delivery management, DLQ

List webhook endpoints

Authorizations:
bearerAuth
query Parameters
page
integer >= 1
Default: 1
per_page
integer [ 1 .. 100 ]
Default: 20
userId
string

Filter by owner (admin only)

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Create a webhook endpoint

Authorizations:
bearerAuth
Request Body schema: application/json
required
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

Responses

Request samples

Content type
application/json
{
  • "secret": "stringstringstri",
  • "events": [
    ],
  • "isActive": true
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Update a webhook endpoint

Authorizations:
bearerAuth
path Parameters
id
required
string
Request Body schema: application/json
required
non-empty
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

Responses

Request samples

Content type
application/json
{
  • "secret": "stringstringstri",
  • "events": [
    ],
  • "isActive": true
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Delete a webhook endpoint

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

List webhook deliveries

Authorizations:
bearerAuth
query Parameters
page
integer >= 1
Default: 1
per_page
integer [ 1 .. 100 ]
Default: 20
pagination
string
Value: "cursor"

Pass cursor to switch to cursor-based pagination

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

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Retry a webhook delivery

Creates a new delivery attempt for the given delivery.

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

List dead-letter queue entries

Returns deliveries that have been dead-lettered (exhausted all retries).

Authorizations:
bearerAuth
query Parameters
page
integer >= 1
Default: 1
per_page
integer [ 1 .. 100 ]
Default: 20
pagination
string
Value: "cursor"

Pass cursor to switch to cursor-based pagination

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"

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Replay a DLQ delivery

Re-dispatches a dead-lettered delivery. The original delivery is marked replayed and a new delivery is created. Admin only.

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Bulk replay DLQ deliveries

Replays multiple dead-lettered deliveries at once. Supports dry-run mode. Admin only, requires Pro+ tier minimum.

Authorizations:
bearerAuth
Request Body schema: application/json
required
ids
required
Array of strings [ 1 .. 100 ] items
dryRun
boolean
Default: false

Responses

Request samples

Content type
application/json
{
  • "ids": [
    ],
  • "dryRun": false
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

merchant-providers

Merchant payment provider configuration

List merchant payment provider configs

Returns the calling merchant's configured providers (credentials are masked).

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Get a merchant provider config by name

Authorizations:
bearerAuth
path Parameters
name
required
string (Provider)
Enum: "mvola" "airtel" "orange"

Mobile money provider

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": { },
  • "error": "string",
  • "meta": {
    }
}

Create or update a merchant provider config

Upserts provider credentials. The client_secret / consumer_secret fields are encrypted at rest and never returned in GET responses.

Authorizations:
bearerAuth
path Parameters
name
required
string (Provider)
Enum: "mvola" "airtel" "orange"

Mobile money provider

Request Body schema: application/json
required
object

Provider-specific config (see MvolaProviderConfig, AirtelProviderConfig, OrangeProviderConfig)

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "success": true,
  • "data": { },
  • "error": "string",
  • "meta": {
    }
}

Delete a merchant provider config

Authorizations:
bearerAuth
path Parameters
name
required
string (Provider)
Enum: "mvola" "airtel" "orange"

Mobile money provider

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

analytics

Payment and subscription analytics (accessible to merchants)

Overall analytics overview

Returns aggregated payment, subscription, and payment link stats. Accessible to merchants and admins.

Authorizations:
bearerAuth
query Parameters
period
string (AnalyticsPeriod)
Default: "month"
Enum: "day" "week" "month"
from
string <date>
to
string <date>

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": { },
  • "error": "string",
  • "meta": {
    }
}

Payment analytics by provider

Authorizations:
bearerAuth
query Parameters
period
string (AnalyticsPeriod)
Default: "month"
Enum: "day" "week" "month"
from
string <date>
to
string <date>

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": { },
  • "error": "string",
  • "meta": {
    }
}

Subscription analytics

Authorizations:
bearerAuth
query Parameters
period
string (AnalyticsPeriod)
Default: "month"
Enum: "day" "week" "month"
from
string <date>
to
string <date>

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": { },
  • "error": "string",
  • "meta": {
    }
}

Daily analytics buckets

Authorizations:
bearerAuth
query Parameters
period
string (AnalyticsPeriod)
Default: "month"
Enum: "day" "week" "month"
from
string <date>
to
string <date>

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

merchant-onboarding

Pro+ merchant onboarding wizard (progress + UAT confirmation)

Get Pro+ onboarding wizard status

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:

  1. providerCredentials — at least one enabled provider config exists.
  2. webhookEndpoint — at least one active webhook endpoint exists.
  3. firstPaymentLink — at least one payment link has been created.
  4. uat — UAT signals are present and confirmation has been submitted.
Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Confirm Pro+ UAT completion

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):

  • Provider credentials configured (step 1 completed)
  • Webhook endpoint active (step 2 completed)
  • At least one payment link created (step 3 completed)
  • At least one completed payment (UAT signal)

Returns 409 if any prerequisite is missing.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

admin

Admin user, token, config, audit-log, and provider management

Admin login

Authenticates an admin user. Returns a JWT and sets an HTTP-only cookie. Rate-limited to 10 req/60s per IP.

Request Body schema: application/json
required
email
required
string <email>
password
string >= 8 characters

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "password": "stringst"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Generate a token for a user

Authorizations:
bearerAuth
Request Body schema: application/json
required
userId
required
string non-empty
name
string [ 1 .. 100 ] characters
ttl
integer >= 1
customClaims
object

Responses

Request samples

Content type
application/json
{
  • "userId": "string",
  • "name": "string",
  • "ttl": 1,
  • "customClaims": { }
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

List tokens

Authorizations:
bearerAuth
query Parameters
page
integer >= 1
Default: 1
per_page
integer [ 1 .. 100 ]
Default: 20
userId
string
status
string
Enum: "active" "revoked" "expired"

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Get token details

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Revoke a token

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

List users

Authorizations:
bearerAuth
query Parameters
page
integer >= 1
Default: 1
per_page
integer [ 1 .. 100 ]
Default: 20
search
string

Search name or email

role
string
Enum: "admin" "user" "customer"

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Create a user

Authorizations:
bearerAuth
Request Body schema: application/json
required
email
required
string <email>
name
required
string [ 1 .. 100 ] characters
role
string
Enum: "admin" "user" "customer"
password
string >= 8 characters

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "name": "string",
  • "role": "admin",
  • "password": "stringst"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Update a user

Authorizations:
bearerAuth
path Parameters
id
required
string
Request Body schema: application/json
required
name
string [ 1 .. 100 ] characters
email
string <email>
role
string
Enum: "admin" "user" "customer"

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "email": "user@example.com",
  • "role": "admin"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Delete a user

Cannot delete a user with payment history (returns 409).

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Get system configuration

Super-admin only. Returns all runtime configuration values.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": { },
  • "error": "string",
  • "meta": {
    }
}

Update system configuration

Super-admin only. Partial update of runtime config values.

Authorizations:
bearerAuth
Request Body schema: application/json
required
object

Partial config update (see updateConfigSchema for all fields)

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "success": true,
  • "data": { },
  • "error": "string",
  • "meta": {
    }
}

List audit logs

Authorizations:
bearerAuth
query Parameters
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

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Export audit logs as CSV

Streams audit logs as a CSV file. Supports date range and field filters.

Authorizations:
bearerAuth
query Parameters
action
string
entityType
string
userId
string
from
string <date-time>
to
string <date-time>

Responses

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "string"
}

List all provider configs (global)

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Get provider config

Authorizations:
bearerAuth
path Parameters
name
required
string (Provider)
Enum: "mvola" "airtel" "orange"

Mobile money provider

query Parameters
userId
string

Get user-specific config instead of global

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Create or update provider config (global)

Upserts global provider credentials. Secrets are encrypted at rest. Masked values (****) in the request preserve existing values.

Authorizations:
bearerAuth
path Parameters
name
required
string (Provider)
Enum: "mvola" "airtel" "orange"

Mobile money provider

Request Body schema: application/json
required
object

Provider-specific config (MvolaProviderConfig, AirtelProviderConfig, OrangeProviderConfig)

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Delete provider config (global)

Authorizations:
bearerAuth
path Parameters
name
required
string (Provider)
Enum: "mvola" "airtel" "orange"

Mobile money provider

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Get tier feature matrix

Returns the SLA tier list, feature flags, and per-tier rate limits.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

marketing

Social media account connection and post management (merchant)

List connected social accounts

Authorizations:
bearerAuth
query Parameters
page
integer >= 1
Default: 1
per_page
integer [ 1 .. 100 ]
Default: 20
platform
string (SocialPlatform)
Enum: "meta" "tiktok"

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Start OAuth connection to social platform

Returns the OAuth authorization URL to redirect the user to.

Authorizations:
bearerAuth
Request Body schema: application/json
required
platform
required
string (SocialPlatform)
Enum: "meta" "tiktok"
redirectUri
required
string <uri>

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {},
  • "error": "string",
  • "meta": {
    }
}

OAuth callback handler

Handles the OAuth redirect from the social platform. Redirects to frontend with status.

path Parameters
platform
required
string (SocialPlatform)
Enum: "meta" "tiktok"
query Parameters
code
required
string
state
required
string

Responses

Response samples

Content type
application/json
{
  • "success": false,
  • "error": "string"
}

Disconnect a social account

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Refresh OAuth token for social account

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

List social posts

Authorizations:
bearerAuth
query Parameters
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

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Create a social post

Creates a draft or scheduled post. If scheduledAt is provided, status is set to scheduled.

Authorizations:
bearerAuth
Request Body schema: application/json
required
socialAccountId
required
string non-empty
content
required
string [ 1 .. 2200 ] characters
mediaUrls
Array of strings <uri> <= 10 items [ items <uri > ]
scheduledAt
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "socialAccountId": "string",
  • "content": "string",
  • "mediaUrls": [],
  • "scheduledAt": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Get post with publish logs

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Update a draft or scheduled post

Only draft or scheduled posts can be updated.

Authorizations:
bearerAuth
path Parameters
id
required
string
Request Body schema: application/json
required
content
string [ 1 .. 2200 ] characters
mediaUrls
Array of strings <uri> <= 10 items [ items <uri > ]
scheduledAt
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "content": "string",
  • "mediaUrls": [],
  • "scheduledAt": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Delete a draft or scheduled post

Only draft or scheduled posts can be deleted.

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Publish post to social platform

Only draft or scheduled posts can be published.

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

Cancel a scheduled post

Reverts a scheduled post back to draft status.

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

admin-marketing

Social media administration (super-admin)

List all social accounts (admin view)

Super-admin only. Lists all social accounts across all users.

Authorizations:
bearerAuth
query Parameters
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"

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Update social account status

Super-admin only. Can activate or revoke accounts.

Authorizations:
bearerAuth
path Parameters
id
required
string
Request Body schema: application/json
required
status
required
string
Enum: "active" "revoked"

Responses

Request samples

Content type
application/json
{
  • "status": "active"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}

List all social posts (admin view)

Super-admin only. Lists all social posts across all users.

Authorizations:
bearerAuth
query Parameters
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

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Get publish logs for a post

Super-admin only. Returns all publish/cancel attempts for a post.

Authorizations:
bearerAuth
path Parameters
id
required
string

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "error": "string",
  • "meta": {
    }
}

Get marketing statistics

Super-admin only. Returns aggregated stats across all social accounts and posts.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    },
  • "error": "string",
  • "meta": {
    }
}