Hakela Investments — API REST
Sistema de Gestão de Água · Moçambique · v1.0
https://apihakela.brilliantmind.co.mz/api
Auth: Sanctum Bearer Token
Tenant: X-Operator-Id header
Formato: JSON
Autenticação & 2FA
Request Body / Params
{"email":"admin@aguas.mz","password":"changeme123!"}
Response (200/201)
{"token":"1|abc...","user":{...}}
Request Body / Params
{}
Response (200/201)
{"message":"Sessão encerrada com sucesso."}
Response (200/201)
{"id":"...","name":"...","roles":[...]}
Request Body / Params
{"email":"user@aguas.mz"}
Response (200/201)
{"message":"Código enviado.","expires_in":600}
Request Body / Params
{"email":"user@aguas.mz","otp":"123456","password":"newpass!","password_confirmation":"newpass!"}
Response (200/201)
{"token":"1|abc...","user":{...}}
Request Body / Params
{"email":"user@aguas.mz","purpose":"password_reset"}
Response (200/201)
{"message":"OTP reenviado.","wait_seconds":0,"resends_left":4}
Request Body / Params
{"challenge_token":"tok...","code":"123456"}
Response (200/201)
{"token":"1|abc...","user":{...}}
Response (200/201)
{"enabled":false,"channel":"email"}
Request Body / Params
{}
Response (200/201)
{"message":"OTP enviado."}
Request Body / Params
{"code":"123456"}
Response (200/201)
{"message":"2FA activado."}
Request Body / Params
{"password":"mypassword"}
Response (200/201)
{"message":"2FA desactivado."}
Request Body / Params
{"channel":"sms"}
Response (200/201)
{"message":"Canal actualizado."}
Utilizadores
Request Body / Params
?search=joão&per_page=20
Response (200/201)
{"data":[...],"meta":{...}}
Request Body / Params
{"name":"João","email":"joao@aguas.mz","password":"pass!","password_confirmation":"pass!"}
Response (200/201)
{"id":"...","name":"João",...}
Response (200/201)
{"id":"...","name":"João","roles":[...]}
Request Body / Params
{"name":"João Silva"}
Response (200/201)
{"id":"...","name":"João Silva"}
Request Body / Params
{"password":"newpass!","password_confirmation":"newpass!"}
Response (200/201)
{"message":"Palavra-passe actualizada."}
Response (200/201)
HTTP 204
Roles & Permissões
Response (200/201)
[{"slug":"super_admin","label":"...","level":100},...]
Response (200/201)
[{"slug":"technician","operator_id":"..."}]
Request Body / Params
{"role_slug":"technician","operator_id":"op_id","expires_at":"2026-12-31"}
Response (200/201)
{"message":"Role atribuído."}
Request Body / Params
{"role_slug":"technician","operator_id":"op_id"}
Response (200/201)
{"message":"Role revogado."}
Consumidores
Request Body / Params
?search=João&type=individual&per_page=20
Response (200/201)
{"data":[...],"meta":{...}}
Request Body / Params
{"name":"João","surname":"Silva","email":"joao@gmail.com","phone_number":"+258841234567","nuit":"123456789","address":{...}}
Response (200/201)
{"id":"...","type":"individual"}
Request Body / Params
{"company_name":"Empresa Lda","nuit":"987654321","phone_number":"+258841234567","address":{...}}
Response (200/201)
{"id":"...","type":"corporate"}
Response (200/201)
{"id":"...","type":"individual","consumerable":{...},"contracts":[...]}
Request Body / Params
{"email":"newemail@gmail.com"}
Response (200/201)
{"id":"..."}
Request Body / Params
{"reason":"Dívida em atraso"}
Response (200/201)
{"message":"Consumidor suspenso."}
Request Body / Params
{}
Response (200/201)
{"message":"Consumidor reactivado."}
Contratos
Request Body / Params
?status=active&consumer_id=...
Response (200/201)
{"data":[...],"meta":{...}}
Request Body / Params
{"consumer_id":"...","operator_id":"...","operational_zone_id":"...","service_type":"domestic","connection_address":{...}}
Response (200/201)
{"id":"...","contract_number":"CTR-2026-0001"}
Response (200/201)
{"id":"...","status":"active","meter":{...},"invoices":[...]}
Request Body / Params
{"operational_zone_id":"..."}
Response (200/201)
{"id":"..."}
Request Body / Params
{"reason":"Fatura em atraso"}
Response (200/201)
{"message":"Contrato suspenso."}
Request Body / Params
{"reason":"Pedido do consumidor"}
Response (200/201)
{"message":"Contrato encerrado."}
Leituras de Contador
Request Body / Params
?contract_id=...&technician_id=...&requires_review=1&per_page=20
Response (200/201)
{"data":[...],"meta":{...}}
Request Body / Params
{"contract_id":"...","technician_id":"...","reading_value":125.5,"read_at":"2026-03-28T10:00:00Z","gps_lat":-25.96,"gps_lng":32.58,"photo_path":null,"notes":"Leitura normal"}
Response (200/201)
{"id":"...","reading_value":125.5,"consumption_m3":8.2}
Response (200/201)
{"id":"...","type":"real","reading_value":125.5,"consumption_m3":8.2,"technician":{...}}
Request Body / Params
{"reading_value":126.0,"correction_reason":"Erro de transcrição — valor lido foi 126.0 m³ e não 125.5","notes":"Correcção após validação no campo"}
Response (200/201)
{"id":"...","reading_value":126.0,"corrected_at":"..."}
Request Body / Params
{"notes":"Verificado — consumo justificado por enchimento de piscina"}
Response (200/201)
{"message":"Leitura marcada como revista."}
Técnicos & Alocações de Zona
valid_from e valid_until (null = sem data de fim). Se existirem alocações dinâmicas, a zona estática do registo do técnico é ignorada.
Request Body / Params
?operator_id=...&status=active
Response (200/201)
{"data":[...],"meta":{...}}
Request Body / Params
{"user_id":"...","operator_id":"...","operational_zone_id":"...","employee_number":"TEC-001","joined_at":"2026-01-01"}
Response (200/201)
{"id":"...","employee_number":"TEC-001"}
Response (200/201)
{"id":"...","user":{...},"operationalZone":{...}}
Request Body / Params
{}
Response (200/201)
{"message":"Técnico suspenso."}
Request Body / Params
{}
Response (200/201)
{"message":"Técnico reactivado."}
Response (200/201)
{"period":"2026-03","score":87.5,"operator_rank":2}
Request Body / Params
?active_only=1
Response (200/201)
[{"id":"...","zone":{"name":"Zona 1 - Polana"},"valid_from":"2026-01-01","valid_until":null,"is_active":true}]
Request Body / Params
{"operational_zone_id":"...","valid_from":"2026-04-01","valid_until":"2026-06-30","notes":"Substituição temporária"}
Response (200/201)
{"message":"Alocação criada.","allocation":{...}}
Request Body / Params
{"valid_until":"2026-05-31","notes":"Extensão do período"}
Response (200/201)
{"message":"Alocação actualizada."}
Response (200/201)
{"message":"Alocação encerrada."}
Faturas
Request Body / Params
?contract_id=...&status=overdue&per_page=20
Response (200/201)
{"data":[...],"meta":{...}}
Response (200/201)
{"id":"...","total_amount":450.00,"status":"pending","line_items":[...]}
Request Body / Params
{"reason":"Leitura incorrecta — corrigida"}
Response (200/201)
{"message":"Fatura cancelada."}
Pagamentos
Request Body / Params
?status=confirmed&invoice_id=...
Response (200/201)
{"data":[...],"meta":{...}}
Request Body / Params
{"invoice_id":"...","amount":450.00,"payment_method":"mpesa","reference":"M-PESA-REF-12345"}
Response (200/201)
{"id":"...","status":"pending"}
Request Body / Params
{}
Response (200/201)
{"message":"Pagamento confirmado."}
Request Body / Params
{"reason":"Pagamento duplicado"}
Response (200/201)
{"message":"Estorno processado."}
KPIs & Relatórios
Request Body / Params
?period=2026-03
Response (200/201)
{"total_consumers":1250,"active_contracts":980,"revenue_mtd":450000,"collection_rate":87.5}
Request Body / Params
?from=2026-01-01&to=2026-03-31&group_by=month
Response (200/201)
{"data":[{"period":"2026-01","amount":145000},...],"total":435000}
Request Body / Params
?period=2026-03
Response (200/201)
{"total":980,"real":910,"estimated":70,"coverage_rate":92.8}
Request Body / Params
?period=2026-03
Response (200/201)
[{"rank":1,"name":"António","score":95.2,"readings":142}]
Request Body / Params
?from=2026-01-01&to=2026-03-31
Response (200/201)
{"new":45,"suspended":12,"terminated":3,"active_total":980}
Request Body / Params
{"period":"daily","email":"gestor@aguas.mz"}
Response (200/201)
{"message":"Relatório enviado."}
Auditoria
Request Body / Params
?user_id=...&event=payment.confirmed&from=2026-03-01&per_page=50
Response (200/201)
{"data":[{"event":"...","user":{},"metadata":{},"created_at":"..."}],"meta":{...}}
Códigos de Resposta
| Código | Significado | Exemplo |
|---|---|---|
| 200 | OK | Pedido processado com sucesso |
| 201 | Created | Recurso criado (POST) |
| 204 | No Content | Eliminação bem-sucedida (DELETE) |
| 401 | Unauthorized | Token em falta ou inválido |
| 403 | Forbidden | Sem permissão (hierarquia ou tenant) |
| 404 | Not Found | Recurso não encontrado |
| 422 | Unprocessable | Validação falhou (ver campo "errors") |
| 423 | Locked | Conta bloqueada por tentativas falhadas |
| 429 | Too Many Requests | Rate limit excedido |
| 500 | Server Error | Erro interno — contacte suporte |