Referência API Bemba
A API Bemba é uma API REST que permite interagir com todas as funcionalidades do sistema.
URL Base
https://sig.example.com/api
Autenticação
A API utiliza JSON Web Tokens (JWT) para a autenticação.
Obter um Token
curl -X POST https://sig.example.com/api/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "password"}'
Resposta:
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
"refresh_token": "abc123...",
"user": {
"id": "0f8fad5b-d9cb-469f-a165-70867728950e",
"email": "user@example.com",
"roles": ["ROLE_USER"],
"nom": "Exemple",
"prenom": "Agent"
}
}
O JWT dura 1 hora, o refresh token 30 dias. Se a autenticação de dois fatores estiver ativada, a resposta traz requires2FA: true e o token obtém-se depois por POST /api/2fa/verify (ver Login).
Sessão por cookies e CSRF
O login define também os cookies BEARER, REFRESH_TOKEN (httpOnly) e XSRF-TOKEN. Um cliente que se apoia nestes cookies (caso do navegador) deve reenviar o valor de XSRF-TOKEN no cabeçalho X-CSRF-TOKEN em cada POST, PUT, PATCH ou DELETE; caso contrário o pedido é recusado com 403. Um cliente que envia apenas o cabeçalho Authorization: Bearer não é afetado.
Utilizador atual e permissões
| Endpoint | Descrição |
|---|---|
GET /api/me | Perfil do utilizador autenticado |
GET /api/me/permissions | Códigos de permissão module.action concedidos (ex. registre.menages_edit) |
Cada endpoint protegido verifica uma permissão deste tipo; os dados devolvidos são também limitados ao perímetro do utilizador (instituição e projetos).
Utilizar o Token
Inclua o token no cabeçalho Authorization:
curl https://sig.example.com/api/menages \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..."
Renovar o Token
curl -X POST https://sig.example.com/api/token/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token": "abc123..."}'
O refresh token é renovado em cada chamada (rotação). A desconexão faz-se por POST /api/token/invalidate (ver Logout).
Formato das Respostas
A API expõe duas famílias de endpoints, com dois formatos.
Controladores de negócio: { success, data }
A maioria dos endpoints (beneficiários, transferências, pagamentos, queixas, seguimento e avaliação, assistente…) devolve:
{
"success": true,
"data": [ { "...": "..." } ],
"pagination": { "page": 1, "limit": 20, "total": 1234, "pages": 62 }
}
pagination só aparece nas listas paginadas (parâmetros page e limit). Em caso de erro: { "success": false, "error": "message" } (ou message) com o código HTTP adequado.
Recursos API Platform: JSON-LD / Hydra
Os recursos de referência (agregados, regiões, setores, localidades, projetos…) seguem o formato Hydra:
{
"@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"
}
}
Enviar Accept: application/json devolve uma tabela JSON simples, sem metadados Hydra.
Os erros destes recursos seguem a RFC 7807 (application/problem+json):
{
"type": "/errors/404",
"title": "An error occurred",
"status": 404,
"detail": "Not Found"
}
Os identificadores são UUID.
Códigos HTTP
| Código | Descrição |
|---|---|
200 | Sucesso |
201 | Recurso criado |
204 | Sucesso sem conteúdo (DELETE) |
400 | Pedido inválido (campo em falta, valor fora da lista) |
401 | Sem sessão: token ausente, expirado ou inválido |
403 | Sessão válida mas permissão em falta, objeto fora do perímetro do utilizador, ou cabeçalho CSRF ausente |
404 | Recurso não encontrado, incluindo para um identificador mal formado (não UUID) |
422 | Erro de validação (recursos API Platform) |
429 | Demasiados pedidos (login, assistente) |
500 | Erro do servidor |
Paginação
Recursos API Platform: parâmetros page e itemsPerPage. O tamanho por defeito depende do recurso (20 para os agregados, 30 nos outros casos); itemsPerPage está limitado a 200. Alguns recursos aceitam pagination=false.
Controladores de negócio: parâmetros page e limit (20 por defeito), resposta no bloco pagination.
curl "https://sig.example.com/api/menages?page=2&itemsPerPage=50" \
-H "Authorization: Bearer TOKEN"
Filtros
Os recursos API Platform filtram por propriedades, muitas vezes pelo identificador da relação:
| Filtro | Descrição | Exemplo |
|---|---|---|
region.id | Filtrar por região | ?region.id=<uuid> |
secteur.id | Filtrar por setor | ?secteur.id=<uuid> |
localite.id | Filtrar por localidade | ?localite.id=<uuid> |
projet.id | Filtrar por projeto | ?projet.id=<uuid> |
statut | Filtrar por estado | ?statut=actif |
order[champ] | Ordenação | ?order[createdAt]=desc |
Os controladores de negócio utilizam parâmetros simples próprios de cada endpoint (search, statut, projet_id, region…): ver a página de cada endpoint.
Endpoints Principais
Autenticação
| Método | Endpoint | Descrição |
|---|---|---|
| POST | /api/login | Login |
| POST | /api/2fa/verify | Código de autenticação de dois fatores |
| POST | /api/token/refresh | Renovar o token |
| POST | /api/token/invalidate | Desconexão |
| GET | /api/me | Utilizador atual |
| GET | /api/me/permissions | Permissões do utilizador |
Agregados familiares
| Método | Endpoint | Descrição |
|---|---|---|
| GET | /api/menages | Lista dos agregados |
| GET | /api/menages/\{id\} | Detalhe de um agregado |
| POST | /api/menages | Criar um agregado |
| POST | /api/menages/\{id\}/update | Modificar um agregado (formulário completo) |
| DELETE | /api/menages/\{id\} | Eliminar um agregado |
Beneficiários
| Método | Endpoint | Descrição |
|---|---|---|
| GET | /api/beneficiaires | Lista dos beneficiários |
| GET | /api/beneficiaires/\{id\} | Detalhe de um beneficiário |
Transferências (ciclos de pagamento)
| Método | Endpoint | Descrição |
|---|---|---|
| GET | /api/cycles | Lista das transferências |
| POST | /api/cycles | Criar uma transferência |
| POST | /api/cycles/\{id\}/generate-payments | Gerar os pagamentos |
| POST | /api/cycles/\{id\}/soumettre | Submeter para validação |
| POST | /api/cycles/\{id\}/valider | Validar o nível seguinte |
Outros módulos
| Prefixo | Descrição |
|---|---|
/api/plaintes | Mecanismo de gestão de queixas (ver Queixas) |
/api/suivi-evaluation | PTBA, indicadores, riscos, missões (ver Seguimento e Avaliação) |
/api/assistant | Assistente Bemba (ver Assistente) |
/api/photos | Fotografias servidas por URL assinada (ver Fotografias) |
Exemplos de Código
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"]
]);