REST API · v1 · Base URL: api.findr.ng

Build with Findr'sMissing 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.

example request
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.

01

Register

Submit your name, email, organisation, and use case. Your API key is issued instantly — no waiting, no approval queue.

02

Test

Your key starts in test mode. All responses use fictional seed data so you can build and validate your integration safely.

03

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_key

Query param

GET /missing-persons?api_key=fndr_your_key

Endpoints

GET/missing-persons

List 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 location
status"missing" | "found"— Filter by case status
statestring— Filter by Nigerian state (e.g. Lagos)
pagenumber— Page number (default: 1)
limitnumber— Results per page (max: 100, default: 20)
GET/missing-persons/:slug

Retrieve 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).

GET/me

Returns 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.published

Fires the moment a submitted case clears review and goes live on the registry.

case.found

Fires 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_key

Environments

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 mode field 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.

developers@findr.ng

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.

EndpointLimit
Per API key, live mode1,000 requests / hour
Per API key, test mode100 requests / hour
Per IP, all developer endpoints300 requests / 15 minutes
API key registration1 active key per email

Errors

Error reference

All errors return a JSON body with a message field and, where applicable, a code field.

HTTP codeMeaning
401No API key provided
401Key not recognised
403Key has been revoked
400Validation error (see message)
429Rate limit exceeded

Example error response

{
  "error": true,
  "code": "invalid_api_key",
  "message": "The API key provided is not recognised."
}