Bemba API Reference
The Bemba API is a REST API that allows interaction with all system features.
Base URL
https://sig.example.com/api
Authentication
The API uses JSON Web Tokens (JWT) for authentication.
Getting a Token
curl -X POST https://sig.example.com/api/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "password"}'
Response:
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
"refresh_token": "abc123...",
"user": {
"id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"email": "user@example.com",
"roles": ["ROLE_USER"],
"nom": "Exemple",
"prenom": "Agent"
}
}
The JWT lasts 1 hour, the refresh token 30 days. If two-factor authentication is enabled, the response carries requires2FA: true and the token is then obtained through POST /api/2fa/verify (see Login).
Cookie session and CSRF
Login also sets the BEARER, REFRESH_TOKEN (httpOnly) and XSRF-TOKEN cookies. A client relying on these cookies (the browser case) must send the XSRF-TOKEN value back in the X-CSRF-TOKEN header on every POST, PUT, PATCH or DELETE, otherwise the request is refused with 403. A client that only sends the Authorization: Bearer header is not affected.
Current user and permissions
| Endpoint | Description |
|---|---|
GET /api/me | Profile of the logged-in user |
GET /api/me/permissions | Granted module.action permission codes (e.g. registre.menages_edit) |
Every protected endpoint checks a permission of this kind; returned data is also limited to the user's scope (institution and projects).
Using the Token
Include the token in the Authorization header:
curl https://sig.example.com/api/menages \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..."
Refreshing the Token
curl -X POST https://sig.example.com/api/token/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token": "abc123..."}'
The refresh token is renewed on every call (rotation). Logout is done through POST /api/token/invalidate (see Logout).
Response Format
The API exposes two families of endpoints, with two formats.
Business controllers: { success, data }
Most endpoints (beneficiaries, transfers, payments, complaints, monitoring and evaluation, assistant…) return:
{
"success": true,
"data": [ { "...": "..." } ],
"pagination": { "page": 1, "limit": 20, "total": 1234, "pages": 62 }
}
pagination only appears on paginated lists (page and limit parameters). On error: { "success": false, "error": "message" } (or message) with the appropriate HTTP code.
API Platform resources: JSON-LD / Hydra
Reference resources (households, regions, sectors, localities, projects…) follow the Hydra format:
{
"@context": "/api/contexts/Menage",
"@id": "/api/menages",
"@type": "hydra:Collection",
"hydra:totalItems": 1234,
"hydra:member": [ { "@id": "/api/menages/0f8fad5b-…", "@type": "Menage", "codeMenage": "…" } ],
"hydra:view": {
"@id": "/api/menages?page=1",
"@type": "hydra:PartialCollectionView",
"hydra:first": "/api/menages?page=1",
"hydra:last": "/api/menages?page=62",
"hydra:next": "/api/menages?page=2"
}
}
Sending Accept: application/json returns a plain JSON array, without Hydra metadata.
Errors from these resources follow RFC 7807 (application/problem+json):
{
"type": "/errors/404",
"title": "An error occurred",
"status": 404,
"detail": "Not Found"
}
Identifiers are UUIDs.
HTTP Codes
| Code | Description |
|---|---|
200 | Success |
201 | Resource created |
204 | Success without content (DELETE) |
400 | Invalid request (missing field, value not in list) |
401 | No session: token missing, expired or invalid |
403 | Valid session but missing permission, object outside the user's scope, or missing CSRF header |
404 | Resource not found, including for a malformed (non-UUID) identifier |
422 | Validation error (API Platform resources) |
429 | Too many requests (login, assistant) |
500 | Server error |
Pagination
API Platform resources: page and itemsPerPage parameters. The default size depends on the resource (20 for households, 30 otherwise); itemsPerPage is capped at 200. Some resources accept pagination=false.
Business controllers: page and limit parameters (20 by default), response in the pagination block.
curl "https://sig.example.com/api/menages?page=2&itemsPerPage=50" \
-H "Authorization: Bearer TOKEN"
Filters
API Platform resources filter on properties, often by relation identifier:
| Filter | Description | Example |
|---|---|---|
region.id | Filter by region | ?region.id=<uuid> |
secteur.id | Filter by sector | ?secteur.id=<uuid> |
localite.id | Filter by locality | ?localite.id=<uuid> |
projet.id | Filter by project | ?projet.id=<uuid> |
statut | Filter by status | ?statut=actif |
order[champ] | Sorting | ?order[createdAt]=desc |
Business controllers use simple parameters specific to each endpoint (search, statut, projet_id, region…): see each endpoint's page.
Main Endpoints
Authentication
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/login | Login |
| POST | /api/2fa/verify | Two-factor authentication code |
| POST | /api/token/refresh | Refresh token |
| POST | /api/token/invalidate | Logout |
| GET | /api/me | Current user |
| GET | /api/me/permissions | User permissions |
Households
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/menages | List households |
| GET | /api/menages/\{id\} | Household details |
| POST | /api/menages | Create a household |
| POST | /api/menages/\{id\}/update | Update a household (full form) |
| DELETE | /api/menages/\{id\} | Delete a household |
Beneficiaries
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/beneficiaires | List beneficiaries |
| GET | /api/beneficiaires/\{id\} | Beneficiary details |
Transfers (payment cycles)
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/cycles | List transfers |
| POST | /api/cycles | Create a transfer |
| POST | /api/cycles/\{id\}/generate-payments | Generate payments |
| POST | /api/cycles/\{id\}/soumettre | Submit for validation |
| POST | /api/cycles/\{id\}/valider | Validate the next level |
Other modules
| Prefix | Description |
|---|---|
/api/plaintes | Grievance redress mechanism (see Complaints) |
/api/suivi-evaluation | Work plan, indicators, risks, missions (see Monitoring & Evaluation) |
/api/assistant | Bemba assistant (see Assistant) |
/api/photos | Photos served through signed URLs (see Photos) |
Code Examples
JavaScript (Fetch)
const login = async (email, password) => {
const response = await fetch('https://sig.example.com/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
return response.json();
};
const getMenages = async (token) => {
const response = await fetch('https://sig.example.com/api/menages', {
headers: { 'Authorization': `Bearer ${token}` }
});
return response.json();
};
Python (Requests)
import requests
# Login
response = requests.post(
'https://sig.example.com/api/login',
json={'email': 'user@example.com', 'password': 'password'}
)
token = response.json()['token']
# Get menages
menages = requests.get(
'https://sig.example.com/api/menages',
headers={'Authorization': f'Bearer {token}'}
).json()
PHP (Guzzle)
use GuzzleHttp\Client;
$client = new Client(['base_uri' => 'https://sig.example.com/api']);
// Login
$response = $client->post('/api/login', [
'json' => ['email' => 'user@example.com', 'password' => 'password']
]);
$token = json_decode($response->getBody())->token;
// Get menages
$menages = $client->get('/api/menages', [
'headers' => ['Authorization' => "Bearer $token"]
]);