Keepable docs
Sender API

Recipient matching

Check which of your recipients are reachable on Keepable before you spend work composing mail. Match in batches by NIN, email, or TIN.

Before you compose a letter, render a PDF, or kick off an agreement, you want to know: is this person actually on Keepable? Recipient matching answers that. You send a batch of identifiers; Keepable returns the subset that is reachable.

Matching is a privacy-preserving membership check. It tells you which of the identifiers you already hold belong to a registered recipient: it never lets you enumerate or discover recipients you do not already know.

Matching requires the content.read scope. It is a read: it never delivers anything or notifies the recipient.

Three identifier types

A recipient can be addressed three ways, each with its own endpoint. All three take a batch and return only the matches.

National Identification Number, 11 digits. The primary identifier for individuals.

curl https://api.keepable.co/tenants/ten_01HXP/recipient_match/nin \
  -H "Authorization: Bearer $KEEPABLE_TOKEN" \
  -H "Keepable-Version: 2026-05-24" \
  -H "Content-Type: application/json" \
  -d '{ "nins": ["12345678901", "10987654321"] }'
200 OK: only the reachable NINs come back
{ "matched_nins": ["12345678901"] }

For recipients you know by email rather than NIN.

curl https://api.keepable.co/tenants/ten_01HXP/recipient_match/email \
  -H "Authorization: Bearer $KEEPABLE_TOKEN" \
  -H "Keepable-Version: 2026-05-24" \
  -H "Content-Type: application/json" \
  -d '{ "emails": ["ada@example.ng", "uche@example.ng"] }'
200 OK
{ "matched_emails": ["ada@example.ng"] }

Tax Identification Number, for addressing companies rather than individuals.

curl https://api.keepable.co/tenants/ten_01HXP/recipient_match/tin \
  -H "Authorization: Bearer $KEEPABLE_TOKEN" \
  -H "Keepable-Version: 2026-05-24" \
  -H "Content-Type: application/json" \
  -d '{ "tins": ["12345678-0001", "87654321-0001"] }'
200 OK
{ "matched_tins": ["12345678-0001"] }

The response always contains only the matched subset. An identifier you sent that is absent from the response is not reachable: that recipient has not signed up (yet).

Matching, then sending

The unmatched recipients are the interesting ones. You have two strategies, and they are not mutually exclusive:

Deliver to the matched set now. They have an inbox; the content arrives immediately. Loop the matched_nins into content delivery.

Retain for the unmatched set. Send those with a retention_days window (30 or 390). Keepable holds the item and delivers it the moment that person registers, and fires a recipient.registered webhook so you know it happened.

This is why a delivery can succeed with status: "retained": you do not have to match first if you are willing to retain. Matching is the optimisation that lets you decide per recipient, and avoid composing expensive content for someone who will not see it for months.

Matching is a point-in-time snapshot. Someone unmatched today may register tomorrow. Do not cache match results as a permanent "not a customer" signal: re-check, or lean on retention plus the recipient.registered webhook.

Batch sizing

Send identifiers in batches rather than one call per recipient: it is both faster and easier on rate limits. Each request is bounded by the standard body limits; for very large lists, page through your own data in chunks (a few thousand identifiers per call is comfortable) and union the results.