Build with Findr's
Missing Persons API
Query Nigeria's public missing persons registry. Every case is verified by a person before it is published, and served as JSON over a documented REST API. The same cases are published separately as an OASIS CAP v1.2 alert feed, the format national alerting systems consume. Built for civic tech developers, newsrooms and researchers.
GET https://api.findr.ng/api/v1/developer/missing-persons Authorization: Bearer fndr_your_key ?state=Lagos&status=missing&limit=20 ← 200 OK · Returns paginated list of cases
Getting started
How it works
Three steps from registration to live data.
Register
Submit your name, email, organisation, and use case. Your API key is issued instantly — no waiting, no approval queue.
Test
Your key starts in test mode. All responses use fictional seed data so you can build and validate your integration safely.
Go Live
Once you're ready, request a live mode promotion. You'll gain access to real, approved missing persons cases.
Registration
Get your API key
Register below to receive an API key instantly. Your key starts in test mode — use it to build and test your integration with fictional seed data.
Instant key issuance
No waiting, no approval queue
Test mode included
Safe sandbox with realistic data
Live mode on request
Access real approved cases
Reference
API Reference
Base URL: https://api.findr.ng/api/v1/developer
Authentication
All requests require your API key, passed either as a header or query parameter:
Header (recommended)
Authorization: Bearer fndr_your_keyQuery param
GET /missing-persons?api_key=fndr_your_keyEndpoints
/missing-personsList missing persons cases. Respects your key's mode — test keys return seed data, live keys return real approved cases.
Query parameters
qstring— Search by name or last seen locationstatus"missing" | "found"— Filter by case statusstatestring— Filter by Nigerian state (e.g. Lagos)pagenumber— Page number (default: 1)limitnumber— Results per page (max: 100, default: 20)/missing-persons/:slugRetrieve a single missing persons case by its unique slug identifier.
The slug is returned in list responses as the slug field (e.g. amaka-okafor-abc123).
/meReturns information about your API key: name, email, mode (test/live), total request count, and last used timestamp.
Example response
GET /missing-persons
{
"mode": "test",
"notice": "Test mode — all records are fictional and for development use only.",
"data": [
{
"id": "6a9188153b230d41df0e859d",
"name": "Amaka Okafor",
"nickname": "Ama",
"slug": "amaka-okafor-3840",
"caseNumber": "FND26-0007",
"age": 24,
"gender": "female",
"height": "165",
"hairStyle": "Braided, shoulder length",
"distinctiveFeatures": "Small scar on left wrist",
"status": "missing",
"vulnerabilityFlag": false,
"lastSeenDate": "2026-09-14",
"lastSeenTime": "18:30",
"lastSeenLocation": "Adeniran Ogunsanya, Surulere, Lagos, Nigeria",
"lastSeenWearing": "Blue denim jacket, white top",
"location": {
"street": "Adeniran Ogunsanya",
"city": "Surulere",
"lga": "Surulere",
"state": "Lagos",
"country": "Nigeria"
},
"circumstances": "Left for work and did not arrive.",
"photo": "https://res.cloudinary.com/.../findr/missing-persons/abc123.jpg",
"resolvedAt": null,
"createdAt": "2026-09-15T08:12:00.000Z",
"updatedAt": "2026-09-15T09:40:00.000Z"
}
],
"pagination": {
"total": 1,
"page": 1,
"limit": 20,
"totalPages": 1,
"hasNextPage": false,
"hasPrevPage": false
}
}Webhooks
Get cases pushed to you
Instead of polling /missing-persons on a schedule, set a webhook URL and Findr will call it the moment a case changes state. One field to set, two events to handle.
Events
case.publishedFires the moment a submitted case clears review and goes live on the registry.
case.foundFires the moment a published case is marked resolved — the person has been found.
Set your webhook URL
Set it once on your key with a PATCH request. The first time you set it, we generate a signing secret and return it in the response — save it, it is shown only once.
PATCH /developer/me
Authorization: Bearer fndr_your_key
Content-Type: application/json
{
"webhookUrl": "https://yourapp.com/webhooks/findr"
}Clear it by sending an empty string. Changing the URL keeps the same secret.
Verify the signature
Every request carries an X-Findr-Signature header — an HMAC-SHA256 of the raw request body, signed with your webhook secret. Recompute it on your end before trusting the payload, so a request that didn't come from Findr gets rejected rather than processed.
const crypto = require('crypto');
const expected = 'sha256=' + crypto
.createHmac('sha256', webhookSecret)
.update(rawRequestBody)
.digest('hex');
if (expected !== req.headers['x-findr-signature']) {
return res.status(401).send('invalid signature');
}Use the raw, unparsed body for this — not the re-serialized JSON — or the signature won't match.
Payload shape
POST to your URL, body below — data is the same case object the REST API returns.
{
"event": "case.published",
"id": "evt_7a2f9c1b4e6d8a90",
"createdAt": "2026-10-09T14:02:11.000Z",
"data": {
"name": "Amaka Okafor",
"caseNumber": "FND26-0007",
"status": "missing",
"lastSeenLocation": "Adeniran Ogunsanya, Surulere, Lagos, Nigeria",
"photo": "https://res.cloudinary.com/.../abc123.jpg"
}
}Test it before you go live
Trigger a one-off delivery to your configured URL, signed exactly like a real event, with test: true and a fictional case so you can wire up handling without waiting for a real one to publish.
POST /developer/me/webhook/test
Authorization: Bearer fndr_your_keyEnvironments
Test vs Live mode
Test mode
mode: "test"
- —Returns fictional sandbox data only — no real cases are ever exposed
- —Safe to use during development — no real cases exposed
- —All responses include a
modefield and a notice header - —Default for all newly registered keys
Live mode
mode: "live"
- —Returns real, approved missing persons cases
- —Only accessible after a manual review and promotion
- —Requires responsible and lawful use of the data
- —Same API, same endpoints — only your key changes
Ready to go live?
Email us to request live mode promotion. We'll review your use case and get back to you.
Limits
Rate limits
Findr is a civic tech platform. The limits below are what the API enforces today, and every response carries standard RateLimit headers so you can read your remaining quota. Contact us if you need higher volumes for research or institutional use.
| Endpoint | Limit |
|---|---|
| Per API key, live mode | 1,000 requests / hour |
| Per API key, test mode | 100 requests / hour |
| Per IP, all developer endpoints | 300 requests / 15 minutes |
| API key registration | 1 active key per email |
Errors
Error reference
All errors return a JSON body with a message field and, where applicable, a code field.
| HTTP code | Meaning |
|---|---|
| 401 | No API key provided |
| 401 | Key not recognised |
| 403 | Key has been revoked |
| 400 | Validation error (see message) |
| 429 | Rate limit exceeded |
Example error response
{
"error": true,
"code": "invalid_api_key",
"message": "The API key provided is not recognised."
}