kestrel

Documentation

Everything you need to integrate Kestrel into your application.

Introduction

Kestrel is a REST API for reverse lookup and identity enrichment. Query by email, phone, or domain and get back structured JSON — names, addresses, phone numbers, DOB, and optional deep background enrichment.

All responses are JSON. Both GET and POST are supported on every endpoint.

Base URL

https://kestrelapi.com
All endpoints accept GET and POST. For POST, send params as application/x-www-form-urlencoded.

Authentication

Pass your API key as api_key on every request — as a query string parameter or in the POST body. Keys are prefixed kst_.

GET request

GET https://kestrelapi.com/lookup/email?api_key=kst_your_key&q=john@example.com

POST request

POST https://kestrelapi.com/lookup/email
Content-Type: application/x-www-form-urlencoded

api_key=kst_your_key&q=john@example.com

User-Agent Requirement

All requests must include a browser-like User-Agent. Requests from HTTP libraries using their default agent are rejected with 403.

Accepted

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/122.0.0.0 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/122.0.0.0 Safari/537.36
Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0

Rejected

python-requests/2.32.3    — blocked
curl/7.68.0               — blocked
Go-http-client/1.1        — blocked
(empty / missing)         — blocked

Email Lookup

Look up a person by email address. Returns name, DOB, addresses, phone numbers, and optional deep enrichment.

GET /lookup/email lookup:email
ParameterTypeDescription
api_keystringrequiredYour API key
qstringrequiredEmail address to search
carrierbooloptionalPhone carrier and line type +$0.0006
deepbooloptionalDeep enrichment via TLO — only charged on match +$0.0033
Request
Response
curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0" \ "https://kestrelapi.com/lookup/email?api_key=kst_your_key&q=john.doe@gmail.com&deep=1"
{ "email": "john.doe@gmail.com", "name": "John Doe", "dob": "1985-03-12", "age": 39, "numbers": [ { "number": "+12125550100", "carrier": "Verizon Wireless", "line_type": "mobile" } ], "addresses": ["123 Main St, New York, NY 10001"], "alt_names": ["Johnny Doe"], "confirmed_numbers": ["+12125550100"], "_kestrel": { "charged": 0.00726 } }

Phone Lookup

Reverse search a phone number. Supports US and international numbers in E.164 or local format.

GET /lookup/phone lookup:phone
ParameterTypeDescription
api_keystringrequiredYour API key
qstringrequiredPhone number — e.g. +12125550100 or 2125550100
carrierbooloptionalCarrier and line type +$0.0006
deepbooloptionalDeep enrichment +$0.0033
Request
Response
curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0" \ "https://kestrelapi.com/lookup/phone?api_key=kst_your_key&q=%2B12125550100&carrier=1"
{ "phone": "+12125550100", "name": "Jane Smith", "dob": "1990-07-22", "age": 34, "addresses": ["456 Park Ave, New York, NY 10022"], "emails": ["jane.smith@gmail.com"], "carrier": "AT&T Mobility", "line_type": "mobile", "_kestrel": { "charged": 0.00402 } }

Domain Search

Find contacts associated with a domain. Returns all people linked to that domain — useful for lead enrichment and business intelligence.

GET /lookup/domain lookup:domain
ParameterTypeDescription
api_keystringrequiredYour API key
qstringrequiredDomain name — e.g. example.com
Request
Response
curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0" \ "https://kestrelapi.com/lookup/domain?api_key=kst_your_key&q=example.com"
{ "domain": "example.com", "contacts": [ { "name": "Bob Johnson", "email": "bob@example.com", "title": "CEO", "phone": "+13105550199" }, { "name": "Alice Carter", "email": "alice@example.com", "title": "CTO", "phone": "+13105550234" } ], "total": 2, "_kestrel": { "charged": 0.0066 } }

Account Balance

Returns the current prepaid balance for the API key.

GET /account/balance billing:view
ParameterTypeDescription
api_keystringrequiredYour API key
Request
Response
curl "https://kestrelapi.com/account/balance?api_key=kst_your_key"
{ "balance": 24.5000, "currency": "USD" }

Access Logs

Returns recent search activity for the API key.

GET /account/logs analytics:basic
ParameterTypeDescription
api_keystringrequiredYour API key
limitintegeroptionalNumber of records — default 100, max 1000
Request
Response
curl "https://kestrelapi.com/account/logs?api_key=kst_your_key&limit=5"
{ "logs": [ { "id": 1042, "search_type": "email", "status_code": 200, "charged": 0.00605, "created_at": "2024-03-14T15:32:11" }, { "id": 1041, "search_type": "phone", "status_code": 200, "charged": 0.00335, "created_at": "2024-03-14T12:10:02" } ], "total": 156 }

Deep Enrichment

Add deep=1 to any lookup to pull full background records via TLO. Requires first name, last name, city, and state to be present in the base result. If those fields are missing, deep is silently ignored and no charge is applied.

TLO uses match scoring — results only returned at ≥50% confidence. You are never charged for failed enrichment.
GET /lookup/email lookup:email
ParameterTypeDescription
api_keystringrequiredYour API key
qstringrequiredEmail address to search
deepboolrequiredSet to 1 to enable TLO deep enrichment +$0.0033 on match
carrierbooloptionalAlso return carrier and line type +$0.0006
Request
Response
curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0" \ "https://kestrelapi.com/lookup/email?api_key=kst_your_key&q=john.doe@gmail.com&deep=1"
{ "email": "john.doe@gmail.com", "name": "John Doe", "dob": "1985-03-12", "age": 39, "numbers": ["+12125550100"], "addresses": ["123 Main St, New York, NY 10001"], // deep enrichment fields "confirmed_numbers": ["+12125550100"], "phone_numbers_full": [ { "number": "+12125550100", "carrier": "Verizon Wireless", "line_type": "mobile", "first_seen": "2012-04", "spam": false } ], "all_names": [ { "name": "John A Doe", "first_seen": "2010-01", "last_seen": "2024-02" }, { "name": "Johnny Doe", "first_seen": "2008-06", "last_seen": "2015-11" } ], "all_dobs": ["1985-03-12"], "related_persons": [ { "name": "Mary Doe", "relation": "spouse" }, { "name": "James Doe", "relation": "relative" } ], "addresses_structured": [ { "street": "123 Main St", "city": "New York", "state": "NY", "zip": "10001-0001", "county": "New York" } ], "criminal_records": [], "alt_names": ["J Doe"], "censored_numbers": ["(212) 555-XXXX"], "_kestrel": { "charged": 0.00726 } }

Additional fields returned with deep=1

FieldDescription
confirmed_numbersPhone numbers verified against TLO records
phone_numbers_fullFull phone details — line type, carrier, first seen, spam flag
all_namesHistorical name variations with first/last seen dates
all_dobsAll dates of birth on record
related_personsFamily members and associates with relationship type
criminal_recordsCourt records — case numbers, crime types, charges
addresses_structuredStructured address data with county and zip+4
alt_namesAdditional name variations from TLO records
censored_numbersPartially masked numbers from TLO

Phone Recovery Verification

Add recovery_check=1 to an email lookup to verify phone numbers via email provider recovery systems. The API extracts phone numbers from the search result, then runs each recovery module to find a match. Processing stops on the first match to minimise cost.

You are only charged for modules that actually execute. Modules that don't support the email domain are automatically skipped.
GET /lookup/email search:email
ParameterTypeDescription
api_keystringrequiredYour API key
qstringrequiredEmail address to search
recovery_checkboolrequiredSet to 1 to enable Phone Recovery Verification
recovery_modulesobjectoptionalmodule_order[] and enabled_modules[] arrays. Uses profile defaults if omitted.
Basic request
Custom modules
Response
curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0" \ "https://kestrelapi.com/lookup/email?api_key=kst_your_key&q=john@yahoo.com&recovery_check=1"
curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0" \ "https://kestrelapi.com/lookup/email?api_key=kst_your_key&q=john@yahoo.com&recovery_check=1\ &recovery_modules[module_order][]=yahoo\ &recovery_modules[module_order][]=outlook\ &recovery_modules[module_order][]=icloud\ &recovery_modules[enabled_modules][]=yahoo\ &recovery_modules[enabled_modules][]=outlook\ &recovery_modules[enabled_modules][]=icloud"
{ "found": true, "data": { "name": "John Doe", "email": "john.doe@yahoo.com", "numbers": ["+12125550100"] }, "recovery_check": { "matched": true, "matched_number": "+12125550100", "matched_module": "yahoo", "modules_used": ["yahoo"], "cost": 0.0060 }, "_kestrel": { "charged": 0.0102 } }

Supported modules & pricing

ModulePriceSupported domains
icloud$0.0040All domains
outlook$0.0030All domains
yahoo$0.0060yahoo.com and subdomains
aol$0.0060aol.com and subdomains
xfinitycomcast$0.0030comcast.com, xfinity.com
gmxmail$0.0050mail.com, gmx.com, etc.
doordash$0.0030All domains

Response fields — recovery_check object

FieldTypeDescription
matchedbooleanWhether a phone number match was found
matched_numberstringThe phone number that matched (if found)
matched_modulestringThe provider module that found the match
modules_usedarrayModules that were executed (only these are charged)
costfloatTotal cost for recovery verification (sum of executed modules)
Results are cached for 24 hours. Duplicate calls for the same email+phone combination within the cache window are not re-charged.

Rate Limits

The API allows 20 requests per second per API key. Exceeding this returns 429 Too Many Requests. Back off and retry after at least 1 second.

LimitValueScope
req/s20Per API key

Python — bulk at 20 req/s

# Stay within 20 req/s using a thread pool
import time
from concurrent.futures import ThreadPoolExecutor

with ThreadPoolExecutor(max_workers=20) as pool:
    for email in emails:
        pool.submit(search, email)
        time.sleep(0.05)  # 1/20 = 0.05s between dispatches
Need a higher rate limit? Contact us — limits can be raised on a per-key basis.

Error Codes

All errors return a JSON body with an error field and an optional message.

CodeMeaning
200OK — request succeeded
400Bad request — missing or invalid parameters
401Unauthorized — invalid or missing API key
402Payment required — insufficient balance
403Forbidden — bad User-Agent
404Not found
429Rate limited — too many requests
500Server error — try again later

Error response format

{
  "error":   "Insufficient balance",
  "message": "Your account balance is too low to complete this request."
}