> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dojah.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Dojah API reference

> Dojah API reference — verify identities and prevent fraud across Africa with a REST API, Widget SDKs, and no-code hosted flows.

Verify identities and stop fraud across Africa — through a REST API, drop-in Widget SDKs, or no-code hosted flows. This reference covers every endpoint, the SDKs, and the concepts you need to go live.

<Tip>
  **New here?** Jump to [making your first call](#first-call) — create an app, grab your keys, and run it in a few minutes.
</Tip>

## Ways to integrate

Pick the approach that fits your product. Most teams combine the hosted flow for onboarding with direct API calls for specific checks.

<Columns cols={3}>
  <Card title="REST API" icon={<span className="dj-card-emoji">🔌</span>} href="/api-reference/get-started/introduction">
    Call any check directly from your server — KYC, KYB, AML, biometrics, and more.
  </Card>

  <Card title="Widget SDKs" icon={<span className="dj-card-emoji">🧩</span>} href="/api-reference/widget-sdks/react">
    Drop Dojah’s verification UI into web or mobile with a few lines of code.
  </Card>

  <Card title="Hosted flows" icon={<span className="dj-card-emoji">🪄</span>} href="/api-reference/get-started/introduction">
    Build a branded onboarding flow in EasyOnboard — no code required.
  </Card>
</Columns>

## Base URLs

The environment is determined by the base URL you call. Authentication and request bodies are identical across both.

| Environment | Base URL                   | Charges                    |
| ----------- | -------------------------- | -------------------------- |
| Sandbox     | `https://sandbox.dojah.io` | None — mock data           |
| Production  | `https://api.dojah.io`     | Per call, from your wallet |

See [Environments](/api-reference/get-started/environments) for the full comparison and the go-live checklist.

## Authenticate

Every request carries two headers: your `AppId` and your secret key in `Authorization` (sent raw — *not* as `Bearer`). Full details in [Authentication](/api-reference/get-started/authentication).

## Make your first call

Create an app, grab your keys, and make your first authenticated call in sandbox — no charges, no setup beyond an account.

<Steps>
  <Step title="Create an app">
    In the dashboard, go to **Developers → Configuration** and create an app. Copy its `AppId`, public key, and secret key.
  </Step>

  <Step title="Start in sandbox">
    Use the base URL `https://sandbox.dojah.io`. Sandbox returns mock data and never charges your wallet.
  </Step>

  <Step title="Make your first request">
    Send a one-time passcode. In sandbox the OTP is always `1234`, so you can run the full flow for free.
  </Step>

  <Step title="Validate & go live">
    Confirm the code, then switch to production keys and the live base URL when you’re ready.
  </Step>
</Steps>

### Your first request

Set the two auth headers and post to the Messaging endpoint. Swap `{{secret_key}}` and `{{app_id}}` for your own.

`POST /api/v1/messaging/otp`

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://sandbox.dojah.io/api/v1/messaging/otp" \
    -H "Authorization: {{secret_key}}" \
    -H "AppId: {{app_id}}" \
    -H "Content-Type: application/json" \
    -d '{ "sender_id": "Dojah", "destination": "2348012345678", "channel": "sms" }'
  ```

  ```js Node.js theme={null}
  const res = await fetch("https://sandbox.dojah.io/api/v1/messaging/otp", {
    method: "POST",
    headers: {
      Authorization: process.env.DOJAH_SECRET_KEY,
      AppId: process.env.DOJAH_APP_ID,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ sender_id: "Dojah", destination: "2348012345678", channel: "sms" }),
  });
  const data = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.post(
      "https://sandbox.dojah.io/api/v1/messaging/otp",
      headers={
          "Authorization": os.environ["DOJAH_SECRET_KEY"],
          "AppId": os.environ["DOJAH_APP_ID"],
      },
      json={"sender_id": "Dojah", "destination": "2348012345678", "channel": "sms"},
  )
  data = res.json()
  ```
</CodeGroup>

### What you get back

A `200` with a `reference_id` — hold onto it to validate the code the user enters.

```json 200 — OK theme={null}
{
  "entity": {
    "reference_id": "edd37ab5-48ec-4481-8cf9-ba5chu7c41f7",
    "destination": "2348012345678",
    "status": "SMS sent successfully"
  }
}
```

<Warning>
  **Server-side only.** Your secret key must never ship in client code. Make API calls from your backend — see [Authentication](/api-reference/get-started/authentication).
</Warning>

## How billing works

Dojah is pay-as-you-go. Each successful production call draws from a prepaid **wallet**; if the balance is too low a request returns `402 Payment Required`. Sandbox calls are always free. See [Wallet & billing](/api-reference/core-concepts/wallet-billing) for checking your balance and handling low-balance errors.

## Start building

<Columns cols={3}>
  <Card title="Authentication" icon={<span className="dj-card-emoji">🔑</span>} href="/api-reference/get-started/authentication">
    Keys, headers, and keeping secrets safe.
  </Card>

  <Card title="Environments" icon={<span className="dj-card-emoji">🌐</span>} href="/api-reference/get-started/environments">
    Sandbox vs production, and going live.
  </Card>

  <Card title="Sandbox & test data" icon={<span className="dj-card-emoji">🧪</span>} href="/api-reference/get-started/sandbox-test-data">
    Test end-to-end without spending credits.
  </Card>
</Columns>
