API conventions
Base URL
https://app.so-amtar.com/v1All documented routes are relative to this base. Test and live share the same URL: the key's mode (sk_test_ / sk_live_) selects the environment.
Format
- Encoding: UTF-8
- Request content type:
application/json - Response content type:
application/json; charset=utf-8
Common headers
| Header | Direction | Notes |
|---|---|---|
Authorization: Bearer sk_... | to the API | Always required |
Idempotency-Key: <uuid> | to the API | Recommended on POST/PUT/PATCH/DELETE |
Content-Type: application/json | to the API | Required when sending a body |
Accept: application/json | to the API | Optional, JSON by default |
Soamtar-Timestamp / Soamtar-Signature | to the API | Optional request signing (v1=HMAC-SHA256(timestamp.METHOD.path, secret key)) |
X-Request-Id: <id> | from the API | Include it in incident reports |
Idempotent-Replay: true | from the API | Present when the response comes from the idempotency cache |
Response envelope
Success (single object)
{
"data": { "id": "...", "object": "transaction" },
"livemode": false
}Success (paginated collection)
{
"data": [ {}, {} ],
"pagination": {
"total": 142,
"per_page": 25,
"current_page": 1,
"last_page": 6
},
"livemode": false
}Error
{
"error": {
"code": "payment_rejected",
"message": "The selected currency is invalid.",
"documentation_url": "https://app.so-amtar.com/docs/errors#payment_rejected"
}
}Identifiers
| Type | Format | Example |
|---|---|---|
id (all resources) | UUID v4 | 0e85b3c2-7c4f-4f1d-9b3a-1c8a2d4e5f6a |
| Transaction reference | TXN- + uppercase alphanumerics | TXN-1A2B3C4D-ABCDEF123456 |
References are at most 36 characters; allow at least 50 characters in your schema for future changes. Routes accept the UUID OR the reference as path parameter.
Pagination
?per_page=N(a reasonable maximum and a default apply)?page=N(default 1)- The response contains
pagination.{total,per_page,current_page,last_page}
Common filters
| Param | Effect |
|---|---|
status=success | Filter by status |
created_from=2026-10-01 | created_at >= |
created_to=2026-10-31 | created_at <= |
provider=orange_money_sl | Filter by provider |
customer_id=<uuid> | Filter by customer |
Currencies
| Code | Decimals | Smallest amount |
|---|---|---|
SLE | 2 | 0.01 |
USD | 2 | 0.01 |
EUR | 2 | 0.01 |
Amounts are in major units with at most two decimals: 150.00 = 150 leones, 12.50 = 12 leones 50 cents. A more precise amount is rejected, never rounded. SLL (pre-2022 code) is not accepted. Display leones as Le 1,250.00.
Phone numbers
Strict E.164: +23276123456 — +232 then the 8-digit national number. No spaces or dashes. Payouts require the leading +.
Dates
ISO-8601 with time zone: 2026-10-21T09:41:00+00:00. Timestamps are in UTC, which is also Freetown time (Africa/Freetown, GMT, no daylight saving).
HTTP codes
| Code | Meaning |
|---|---|
| 200 | Success, resource returned |
| 201 | Created, resource returned |
| 202 | Accepted, asynchronous processing |
| 204 | Success without content (e.g. DELETE) |
| 400 | Malformed request |
| 401 | Missing or invalid authentication |
| 403 | Valid authentication, insufficient rights |
| 404 | Resource not found |
| 409 | Conflict (idempotency) |
| 422 | Business validation failed |
| 429 | Rate limit |
| 500 | Internal error (report it) |
| 502 | Orange Money unavailable upstream |
| 503 | Planned maintenance |
Versioning
The URL includes the version: /v1. See the versioning policy.
Rate limiting
Rate limits apply per API key and per sensitive endpoint. Exact limits depend on your activity profile; when exceeded you get 429 Too Many Requests with a Retry-After header. Contact support ahead of an expected traffic increase.
Compression
Accept-Encoding: gzip is supported.
CORS
The API is not meant to be called from a browser (it would expose your secret key). Use your server as the intermediary; in the browser, use SOAMTAR.js with your public key.