← Back to app

Mystack API

Embed revenue-splitting bank accounts into your product. Create managed accounts, give each a real NUBAN, define how money splits the moment it lands, and pay out — all over a simple REST API.

Base URL

https://mystack-api.onrender.com

Get an API key

Open the Mystack app → Settings → Developer APIEnable developer API. You’ll get a msk_test_ key instantly to build with, and can mint a msk_live_ key once your BVN is verified (live money access is identity-gated, like every regulated processor).

Authentication

Every request needs your secret API key as a Bearer token. Keep it server-side — never ship it in a browser or mobile app.

curl https://mystack-api.onrender.com/v1/whoami \
  -H "Authorization: Bearer msk_test_xxxxxxxxxxxx"

Response:

{ "developerId": "…", "mode": "test", "scopes": ["accounts","balances","payouts","splits"] }

Test vs. Live mode

  • msk_test_… keys never move real money — payouts are simulated as successful so you can build the full flow safely.
  • msk_live_… keys move real funds. Request a live key once your integration is ready.

Scopes

Each key carries scopes. A call to an endpoint without its scope returns 403.

accountsbalancessplitspayouts

Endpoints

MethodPathScopeDescription
POST/v1/accountsaccountsCreate a managed business + buckets
GET/v1/accounts/:idaccountsAccount overview
GET/v1/accounts/:id/balancesbalancesBucket balances + NUBANs
POST/v1/accounts/:id/splitssplitsSet split percentages
POST/v1/accounts/:id/bank-accountsaccountsAdd a payout destination
POST/v1/accounts/:id/payoutspayoutsPay out from a bucket
GET/v1/webhooks/deliveriesYour webhook delivery history
GET/v1/keysList your API keys

Create an account

Each account gets real bank account numbers, so a valid BVN is required (the bank uses it to open the accounts). Percentages must total 100.

curl -X POST https://mystack-api.onrender.com/v1/accounts \
  -H "Authorization: Bearer msk_test_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "fullName": "Ada Stores",
    "email": "owner@adastores.com",
    "bvn": "22212345678",
    "pots": [
      { "name": "Restock", "percent": 60 },
      { "name": "Profit",  "percent": 20 },
      { "name": "Tax",     "percent": 20 }
    ]
  }'

Pay out (idempotent)

Send an Idempotency-Key header. Retrying with the same key returns the original payout instead of paying twice.

curl -X POST https://mystack-api.onrender.com/v1/accounts/{id}/payouts \
  -H "Authorization: Bearer msk_test_xxxx" \
  -H "Idempotency-Key: 7c1f-restock-2026-06-15" \
  -H "Content-Type: application/json" \
  -d '{
    "potId": "…",
    "amountKobo": 5000000,
    "destinationBankAccountId": "…"
  }'

Amounts are always in kobo (integers). ₦50,000 = 5000000.

Webhooks

Set a webhook URL on your developer account and we POST events (e.g. payment.received) as they happen. Deliveries are retried with backoff; check history at /v1/webhooks/deliveries.

Verify the mystack-signature header — HMAC-SHA256 of the raw body with your webhook secret — and reject events whose at timestamp is stale:

import crypto from 'node:crypto';

function verify(rawBody, signature, secret) {
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

Errors

Errors return a non-2xx status with { "error": "message" }. Common: 401 bad key · 403 missing scope · 400 validation.