> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.senjaropay.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.senjaropay.com/_mcp/server.

# SenjaroPay Documentation

SenjaroPay is a payment API built for African markets. Use it to collect money via mobile money on supported operator networks, and to integrate with your backend using straightforward REST endpoints.

## Base URL

```
https://api.senjaropay.com
```

All request URLs in this documentation are relative to that host unless stated otherwise. Merchant API operations use **POST** with a JSON body.

## Authentication

Every merchant request must include both credentials:

```http
x-api-key: YOUR_API_KEY_HERE
x-api-secret: YOUR_API_SECRET_HERE
```

Treat your API key like a password. Store it in server-side secrets (environment variables, a vault, or your host’s secret manager) and never expose it in client-side code or public repositories.

All payloads and responses shown in this documentation are mock examples for integration guidance only.

## Quick start

* **[Authentication](/authentication)** — Learn how to authenticate requests using API key and API secret.
* **[Mobile money](/create-payment)** — USSD push to authorize.
* **[Payment status](/payment-status)** — Retrieve the status of a payment over **POST** after it is created.
* **[Webhooks](/webhooks)** — Receive real-time notifications when payments update or complete.

## Payment types

### Mobile money

**Type:** mobile money / MNO collection

The customer completes payment on their operator’s network (for example via USSD prompt or wallet flow, depending on channel configuration).

**Supported networks (mobile collection):** Vodacom (M-Pesa), Airtel Money, Tigo Pesa / Mixx by Yas, Halotel.

**Typical use:** airtime-style collections, bill pay, e-commerce with local wallets.

## Integration flow

Create a [SenjaroPay](https://senjaropay.com/) account and generate API keys from the dashboard. Copy the key into your server environment as `YOUR_API_KEY_HERE` (or similar).

Call `POST https://api.senjaropay.com/senjaropay/merchant/payments/create` with mobile money fields (`payment_type`, `details`, `phone_number`, `customer`). Include `x-api-key`, `x-api-secret`, and a unique `x-idempotency-key`.

The customer authorizes the collection on their mobile money wallet (for example USSD or in-app confirmation, depending on the operator). Track the outcome via [payment status](/payment-status) or [webhooks](/webhooks).

Verify success using your chosen mechanism (callback, webhook, or status API) before fulfilling the order or service.

## Idempotency

For create/charge requests (for example `POST https://api.senjaropay.com/senjaropay/merchant/payments/create`), send a unique idempotency key so retries do not create duplicate charges:

```http
POST https://api.senjaropay.com/senjaropay/merchant/payments/create
Content-Type: application/json
x-api-key: YOUR_API_KEY_HERE
x-api-secret: YOUR_API_SECRET_HERE
x-idempotency-key: unique-key-123
```

If you repeat the same request with the same `x-idempotency-key`, you should receive the same outcome as the first successful attempt (exact behavior is defined by the API implementation).

## Rate limits

API traffic may be rate-limited. When limits apply, responses can include headers such as:

| Header                  | Description                                                      |
| ----------------------- | ---------------------------------------------------------------- |
| `X-RateLimit-Limit`     | Maximum requests allowed in the current window                   |
| `X-RateLimit-Remaining` | Requests left before the window resets                           |
| `X-RateLimit-Reset`     | When the current window resets (often as a timestamp or seconds) |

If you receive `429 Too Many Requests`, slow down and retry with exponential backoff (increase delay between attempts).

## Response format

Successful responses typically wrap payloads in a consistent envelope, for example:

**Success**

```json
{
  "status": "success",
  "code": 200,
  "data": {
  }
}
```

Errors return a machine-readable code and a message you can log or show in support tooling:

**Error**

```json
{
  "status": "error",
  "code": 400,
  "error_code": "validation_error",
  "message": "Description of the error"
}
```

Exact field names may match your live API; confirm payloads and status codes against your integration environment and the endpoint definitions in this documentation.