DevelopersDocumentationAPI v1

YOUR NEXT INTEGRATION STARTS HERE

Good data.
Great things to build.

Bring Sudan’s bank availability, telecom status, and currency rates into your product. Find your first request, explore the endpoints, and connect to change events.

BASE URL
https://status.sd/api/open/v1
FORMAT
JSON
CONTRACT
OpenAPI 3.1

Your API at a glance

Download OpenAPI

01 · GET STARTED

First request #

Use a server-side environment and replace the placeholder with a key created in your developer dashboard.

curl "https://status.sd/api/open/v1/dashboard" \
  -H "X-API-Key: sk_live_..." \
  -H "Accept: application/json"

02 · AUTHENTICATION

Keep credentials on the server #

Send your key using either X-API-Key or Authorization: Bearer sk_live_.... If both headers are sent, they must contain the same key. Never expose a live key in a browser or mobile application.

Live key formatsk_live_ + 48 alphanumeric characters

03 · RESILIENCE

Errors and limits #

Successful requests include X-RateLimit-Limit and X-RateLimit-Remaining. Back off when you receive 429 and honor Retry-After when present.

StatusCodeWhat to do
401invalid_api_keyCheck the key, header, and whether the key was revoked.
402subscription_requiredActivate or renew the developer subscription.
422Validation errorsCorrect the named request fields before retrying.
429rate_limit_exceededWait for Retry-After, then retry with jitter.
429quota_exhaustedWait until resets_at or change plans.
503Temporarily unavailableRetry later with exponential backoff.

04 · API REFERENCE

Endpoints

All endpoints require authentication. Select a response code to inspect its exact sample body.

GET/dashboard#

Status dashboard

Returns the current status of every bank and telecom plus public app configuration. Responses are cached for 60 seconds and include an ETag.

Parameters 1
NameLocationRequiredDescription
If-None-MatchheaderNoETag from a previous response.

Request

curl "https://status.sd/api/open/v1/dashboard" \
  -H "X-API-Key: sk_live_..." \
  -H "Accept: application/json"

Responses

Current dashboard snapshot.

{
  "updated_at": "2026-11-08T18:42:11.000000Z",
  "banks": [
    {
      "slug": "bank-of-khartoum",
      "name_ar": "بنك الخرطوم",
      "name_en": "Bank of Khartoum",
      "logo_url": "https://status.sd/storage/banks/bok.png",
      "since": "2026-11-08T18:42:11.000000Z",
      "app_status": "working",
      "android": "working",
      "ios": "working",
      "internal_transfer": "working",
      "zain_recharge": "unstable",
      "sudani_recharge": "working",
      "mtn_recharge": "working",
      "electricity": "working",
      "interbank_transfer": "down",
      "international_transfer": null,
      "subscriber_services": "working",
      "device_change": "working"
    }
  ],
  "telecoms": [
    {
      "slug": "zain",
      "name_ar": "زين",
      "name_en": "Zain",
      "call": "working",
      "internet": "unstable",
      "recharge": "working",
      "since": "2026-11-08T17:00:00.000000Z"
    }
  ],
  "app": {
    "website_url": "https://status.sd",
    "android_url": "https://play.google.com/store/apps/details?id=sd.status",
    "ios_url": ""
  }
}
GET/banks/{slug}/history#

Bank status history

Returns newest-first status intervals that started today (UTC) for one bank. Older records are never exposed by the developer API.

Parameters 4
NameLocationRequiredDescription
slugpathYesThe bank's stable slug.
pagequeryNo
per_pagequeryNoItems per page. Do not combine with `limit`.
limitqueryNoAlias for `per_page`. Do not combine both.

Request

curl "https://status.sd/api/open/v1/banks/bank-of-khartoum/history" \
  -H "X-API-Key: sk_live_..." \
  -H "Accept: application/json"

Responses

A simple-paginated list of status intervals.

{
  "data": [
    {
      "slug": "bank-of-khartoum",
      "name_ar": "بنك الخرطوم",
      "name_en": "Bank of Khartoum",
      "logo_url": "https://status.sd/storage/banks/bok.png",
      "notification_topic": "bank_of_khartoum",
      "since": "2026-11-08T18:42:11.000000Z",
      "app_status": "working",
      "android": "working",
      "ios": "working",
      "internal_transfer": "working",
      "zain_recharge": "unstable",
      "sudani_recharge": "working",
      "mtn_recharge": "working",
      "electricity": "working",
      "interbank_transfer": "down",
      "international_transfer": null,
      "subscriber_services": "working",
      "device_change": "working",
      "started_at": "2026-11-08T18:42:11.000000Z",
      "ended_at": null
    }
  ],
  "links": {
    "first": "https://status.sd/api/open/v1/banks/bank-of-khartoum/history?page=1",
    "next": null,
    "prev": null
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "path": "https://status.sd/api/open/v1/banks/bank-of-khartoum/history",
    "per_page": 50,
    "to": 1
  }
}
GET/currency#

Currency and gold snapshot

Returns the latest bank and parallel-market rates, movement direction, and the latest gold price when available.

Request

curl "https://status.sd/api/open/v1/currency" \
  -H "X-API-Key: sk_live_..." \
  -H "Accept: application/json"

Responses

Latest currency and gold data.

{
  "fetched_at": "2026-11-08T18:42:11.000000Z",
  "source_updated_at": "2026-11-08T18:40:00.000000Z",
  "last_checked_at": "2026-11-08T18:42:11.000000Z",
  "rates": [
    {
      "name": "US Dollar",
      "symbol": "$",
      "code": "USD",
      "bank_rate": 601.5,
      "parallel_rate": 2480,
      "bank_direction": "stable",
      "parallel_direction": "up",
      "details_url": "https://status.sd/currency/usd"
    }
  ],
  "gold": {
    "price": 168500,
    "previous_price": 167000,
    "quoted_on": "2026-11-08",
    "fetched_at": "2026-11-08T18:42:11.000000Z",
    "last_checked_at": "2026-11-08T18:42:11.000000Z"
  }
}
GET/events#

Webhook events

Lists every event code that can be selected on a developer webhook.

Request

curl "https://status.sd/api/open/v1/events" \
  -H "X-API-Key: sk_live_..." \
  -H "Accept: application/json"

Responses

Supported event codes.

{
  "data": [
    {
      "code": "bank.status.changed",
      "description": "A bank service status changed."
    },
    {
      "code": "currency.updated",
      "description": "Currency rates were updated."
    }
  ]
}

05 · WEBHOOKS

Updates delivered to you #

Nabd sends a JSON POST and considers any 2xx response successful. Connections time out after 5 seconds and requests after 10 seconds. Redirects are not followed.

  1. NowAttempt 1
  2. +60 secAttempt 2
  3. +5 minAttempt 3
  4. +30 minFinal attempt
Design for retriesUse X-StatusSD-Delivery to handle duplicate deliveries safely. Do not assume events arrive immediately or in order.
bank.status.changed#

Sent whenever one or more service statuses for a bank change.

Delivery headers 4
HeaderPurpose
X-StatusSD-EventEvent code, such as bank.status.changed
X-StatusSD-DeliveryUnique delivery ID; use it for deduplication
X-StatusSD-TimestampUnix timestamp included in the signature input
X-StatusSD-SignatureHMAC-SHA256 signature prefixed by sha256=

Example payload

{
  "id": 18431,
  "event": "bank.status.changed",
  "created_at": "2026-11-08T18:42:11+00:00",
  "data": {
    "bank": {
      "id": 1,
      "slug": "bank-of-khartoum",
      "name_ar": "بنك الخرطوم",
      "name_en": "Bank of Khartoum"
    },
    "statuses": {
      "app_status": "working",
      "android": "working",
      "ios": "working",
      "internal_transfer": "working",
      "zain_recharge": "unstable",
      "sudani_recharge": "working",
      "mtn_recharge": "working",
      "electricity": "working",
      "interbank_transfer": "down",
      "international_transfer": null,
      "subscriber_services": "working",
      "device_change": "working"
    },
    "changed_at": "2026-11-08T18:42:11.000000Z"
  }
}
currency.updated#

Sent after a new currency snapshot is stored.

Delivery headers 4
HeaderPurpose
X-StatusSD-EventEvent code, such as bank.status.changed
X-StatusSD-DeliveryUnique delivery ID; use it for deduplication
X-StatusSD-TimestampUnix timestamp included in the signature input
X-StatusSD-SignatureHMAC-SHA256 signature prefixed by sha256=

Example payload

{
  "id": 18432,
  "event": "currency.updated",
  "created_at": "2026-11-08T18:45:00+00:00",
  "data": {
    "snapshot_id": 924,
    "fetched_at": "2026-11-08T18:45:00.000000Z",
    "source_updated_at": "2026-11-08T18:40:00.000000Z",
    "rates": [
      {
        "code": "USD",
        "bank_rate": 601.5,
        "parallel_rate": 2480
      }
    ]
  }
}

06 · SECURITY

Verify every signature #

Build the signed value from the exact raw request bytes: timestamp + "." + rawBody. Calculate HMAC-SHA256 with the webhook secret and compare the complete sha256=... value in constant time.

import crypto from "node:crypto";

function verifyWebhook(rawBody, timestamp, signature, secret) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(timestamp + "." + rawBody)
    .digest("hex");

  const actualBuffer = Buffer.from(signature);
  const expectedBuffer = Buffer.from(expected);
  return actualBuffer.length === expectedBuffer.length &&
    crypto.timingSafeEqual(actualBuffer, expectedBuffer);
}