APIs and SDKs
The 221 API and its SDKs at a glance. Find a route, get a key, make a first call, then pick an SDK.
The 221 API publishes reference data to build in Senegal: geography down to the commune, public holidays, banks, operator prefixes, the API directory and regulatory procedures, plus a few tools (business days, amounts in FCFA). It answers in JSON, can be called without a key within a daily limit, and with a free key beyond that.
Where to start
Get started in 5 minutes
A call without sign-up, then a free key.
Authentication and keys
Create a key in the 221 Pay dashboard, quotas with and without a key.
First call
A complete call with a key, the response and the errors, in your language.
221 SDKs
TypeScript, Python and Dart: installation, payments, webhook verification.
Base URL
https://apps.orvlabs.com
The complete OpenAPI 3.1 document is served by the API at /v1/openapi.json.
API reference
Each route: parameters, body, example JSON responses, errors, call examples in cURL, JavaScript, Python, PHP, Go, Dart, Java and C#, and a "Try" button.
221 Pay API reference
Payments, payment links, refunds, payouts and balances, with a key scoped to payments. 49 routes
Tools
Analyse a phone number, format an amount in CFA francs, count business days. 4 routes
Reference data
Directory, procedures, datasets, public holidays, operators, banks: paginated lists and records. 34 routes
Geography
Regions, departments, districts and communes, with their parents and children. 4 routes
Accounts and webhooks
A project’s API keys, usage and webhook subscriptions, from a dashboard session. 31 routes
Reports
Report a data error, follow its status, decide (maintainers). Answers 503 until the form is open (CDP declaration). 2 routes
Quotas
| Call | Daily quota | Counted per |
|---|---|---|
| Without a key | 100 calls | IP address |
| With a key | 1,000 calls | key |
The counter resets at midnight GMT (Senegal time). Each counted response
carries the RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset
headers.
Errors
All errors share the same shape: a stable code to test in your code (not the
HTTP status), a readable message, a request_id (also in the X-Request-Id
header), fields when parameters are rejected, and the members specific to the
code at the same level.
{
"code": "INVALID_REQUEST",
"message": "Invalid parameters.",
"request_id": "2f6c9a0e-5b1d-4e7f-8c3a-9d0b1e2f3a4c",
"fields": { "year": "…" }
}| Status | Code | What to do |
|---|---|---|
| 400 | INVALID_REQUEST | Fix the parameters listed in fields. |
| 401 | INVALID_API_KEY | Check the key, or call without a key. |
| 404 | NOT_FOUND | Check the identifier or the path. |
| 429 | QUOTA_EXCEEDED | Wait Retry-After seconds, or use a key. |
| 503 | DATASET_UNAVAILABLE | The dataset is not published on the API yet. |
The full list of codes is in Errors.