Документация API
API позволяет программно отправлять поисковые запросы и получать структурированный ответ. Базовый адрес — https://lookupyou.com/api/v1, формат обмена — JSON, все даты в ответах — ISO 8601 (UTC). Ниже — живой справочник: он собран из той же OpenAPI-схемы, которую отдаёт сам сервис, и совпадает с его реальным поведением.
Ключ, баланс, пакеты и история запросов — в кабинете. Открыть кабинет
Аутентификация
Каждый запрос подписывается ключом доступа в заголовке Authorization. Ключ создаётся в кабинете и показывается один раз — сохраните его сразу, восстановить нельзя. Дальше в интерфейсе виден только фрагмент вида lp_live_a7f3…9c21.
Authorization: Bearer lp_live_a7f3f0c98b1d4e7aa2b5c8d19c21
Ключ можно ограничить сроком жизни и списком IP-адресов. Если ключ скомпрометирован — отзовите его в кабинете, доступ прекратится немедленно: запросы получат 401 и не будут списаны. Управление ключами
Первый запрос
Минимальный поиск в быстром режиме — программа ждёт результат в том же соединении. Ответ приходит обычно за 6–12 секунд; при очереди дольше.
curl -X POST https://lookupyou.com/api/v1/search \
-H "Authorization: Bearer lp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"product":"ssn_bg","first_name":"John","last_name":"Miller","hint":"1026 Maple Lane","mode":"sync"}'Ответ · 200 OK
{
"request_id": "req_8f21c4",
"client_ref": "order-1187",
"product": "ssn_bg",
"mode": "sync",
"status": "completed",
"query": { "first_name": "John", "last_name": "Miller", "hint": "1026 Maple Lane", "dob": null },
"charged": true,
"charge": { "source": "package", "amount_cents": 0, "requests": 1 },
"cached": false,
"error": null,
"queue_position": 0,
"duration_ms": 7840,
"created_at": "2026-08-17T11:07:12Z",
"finished_at": "2026-08-17T11:07:20Z",
"result_expires_at": "2026-11-15T11:07:20Z",
"result": {
"found": true,
"matches_count": 1,
"records": [{ "full_name": "MILLER, JOHN A", "ssn": "445-72-4417", "dob": "3/14/1979", "age": 47, "addresses": [ … ], "phones": [ … ] }]
}
}Обязательны product, first_name и last_name плюс хотя бы одно уточнение: hint (улица без индекса, город или штат) или dob (дата рождения MM/DD/YYYY). Без уточнения источник не ищет — ответ 422, ничего не списывается.
Быстрый и отложенный режим
Источник данных допускает один активный сеанс, поэтому поиски выполняются последовательно. Поле mode определяет, как вы получите результат:
- sync (по умолчанию) — соединение держится до готовности результата. Подходит для единичных поисков по действию пользователя. Таймаут на нашей стороне — 5 минут.
- async — API сразу возвращает 202 Accepted с позицией в очереди, а готовый результат приходит на ваш вебхук событием search.completed или search.failed. Результат в любой момент можно забрать и через GET /requests/{id}. Единственный удобный вариант при потоке запросов.
Очередь и ожидание
В ответе 202 есть поля queue_position и eta_seconds — сколько запросов впереди и сколько примерно ждать; в заголовках синхронного ответа — X-Queue-Position. Текущую длину очереди отдаёт GET /queue. Очередь честная: приоритетов нет ни у одного тарифа.
Одновременно в работе может быть не больше 8 ваших запросов; сверх — 429 too_many_running. Для потока это не помеха: отправляйте следующий, когда получите ответ или уведомление.
Докупки к найденному человеку
Если поиск SSN + DOB нашёл человека, номер прав (DL) и выписку MVR можно взять из той же записи без второго обращения к источнику — дешевле и мгновенно: POST /requests/{id}/addons с полем addon. Если нужного куска в записи нет, ответ придёт со статусом not_found и без списания. Повторная докупка того же — бесплатно из сохранённого.
| Докупка | После какого продукта | Что в ответе | Цена |
|---|
| dl_after_ssn | ssn_bg | Номер прав и штат выдачи | $1.00 |
| mvr_after_ssn | ssn_bg | Даты выдачи и окончания прав, иногда пол, раса, рост | $7.50 |
| mvr_after_dl | dl | То же — по уже купленному номеру прав | $5.00 |
Кредитный отчёт (CR and CS) по API пока не выдаётся — 409 addon_unavailable. Он оформляется через поддержку.
Методы
Все пути относительно базового адреса. Все методы требуют заголовок Authorization: Bearer <ключ>.
POST/searchRun a search
Sync mode holds the connection until the source answers (usually 6–12 seconds, longer under queue). Async mode returns 202 immediately; the result is delivered to your webhook and stays available via GET /requests/{id}. Only a completed search is charged: a validation error, an unavailable source or a rate-limit rejection cost nothing.
Тело запроса
| Поле | Тип | Описание | Пример |
|---|
| productобяз. | ssn_bg | dl | mvr | ssn_bg — SSN + DOB (package or balance), dl / mvr — balance only | |
| first_nameобяз. | string | | John |
| last_nameобяз. | string | | Miller |
| hint | string | Street without ZIP, city or state. Required unless dob is given | 1026 Maple Lane |
| dob | string | MM/DD/YYYY. Required unless hint is given | 03/14/1979 |
| mode | sync | async | (default: sync) | |
| client_ref | string | Your identifier, echoed back in responses and webhooks | |
Ответы
200Search finished (found or not found)Request 202Accepted into the queue (async mode)Accepted 401Missing, invalid, revoked or expired API keyError 402Not enough funds: no package requests left and balance is below the product priceError 403IP address is not allowed for this key, or the account is suspendedError 422Validation error — the search was not sent to the sourceError 429Rate limit: 60 requests per minute per account, or too many requests running at onceError 503Source did not answer; nothing was chargedError GET/requestsList recent requests
Параметры
| Имя | Где | Тип | Описание |
|---|
| limit | query | integer | |
| before | query | string | Return requests created before this ISO timestamp (pagination) |
| status | query | queued | running | completed | not_found | failed | rejected | |
Ответы
200Requests without result bodies
GET/requests/{id}Get a request with its result
Параметры
| Имя | Где | Тип | Описание |
|---|
| idобяз. | path | string | |
Ответы
404Unknown request idError GET/requests/{id}/reportFull report as plain text
Параметры
| Имя | Где | Тип | Описание |
|---|
| idобяз. | path | string | |
Ответы
404No result for this request (not finished, failed, or expired)Error POST/requests/{id}/addonsBuy an add-on from a saved result
Driver licence or MVR taken from the record already found — no second call to the source, so it is cheaper and instant. If the record has no such data, the answer is `not_found` and nothing is charged. Already bought add-ons are returned again for free.
Параметры
| Имя | Где | Тип | Описание |
|---|
| idобяз. | path | string | |
Тело запроса
| Поле | Тип | Описание | Пример |
|---|
| addonобяз. | dl_after_ssn | mvr_after_ssn | mvr_after_dl | | |
Ответы
402Balance is below the add-on priceError 404Unknown request idError 409Add-on is not applicable to this request, or the credit report is not available via API yetError GET/accountBalance, packages and prices
Ответы
GET/queueQueue length at the source
Ответы
Объекты
Поля объектов ответа. Типы указаны по JSON Schema; поля со значением null допускают отсутствие данных.
Error
| Поле | Тип | Описание |
|---|
| error | string | · Пример: payment_required |
| message | string | |
| charged | "false" | |
| retry_after | integer | seconds, only with 429 |
Accepted
| Поле | Тип | Описание |
|---|
| request_id | string | · Пример: req_8f21c4 |
| status | "queued" | |
| queue_position | integer | |
| eta_seconds | integer | |
Request
| Поле | Тип | Описание |
|---|
| request_id | string | |
| client_ref | string | null | |
| product | string | |
| mode | sync | async | |
| status | queued | running | completed | not_found | failed | rejected | |
| query | object | |
| query.first_name | string | |
| query.last_name | string | |
| query.hint | string | null | |
| query.dob | string | null | |
| charged | boolean | |
| charge | object | |
| charge.source | package | balance | none | |
| charge.amount_cents | integer | |
| charge.requests | integer | |
| charge.reason | string | null | |
| cached | boolean | Same query within 5 minutes — served from the saved answer for free |
| error | object | null | |
| error.code | string | |
| error.message | string | null | |
| queue_position | integer | null | |
| duration_ms | integer | null | |
| created_at | string | |
| finished_at | string | null | |
| result_expires_at | string | null | Results are kept for 90 days |
| result | Result | null | |
Result
| Поле | Тип | Описание |
|---|
| found | boolean | |
| matches_count | integer | |
| records | Person[] | |
PersonFor ssn_bg: identity, addresses, phones, emails, relatives, civil records. For dl: name and licence numbers. For mvr: licences with dates.
| Поле | Тип | Описание |
|---|
| full_name | string | |
| ssn | string | null | |
| dob | string | null | · Пример: 3/14/1979 |
| age | integer | null | |
| gender | string | null | |
| aka | string[] | |
| addresses | object[] | |
| addresses[].raw | string | |
| addresses[].city | string | null | |
| addresses[].state | string | null | |
| addresses[].zip_code | string | null | |
| addresses[].date_from | string | null | |
| addresses[].date_to | string | null | |
| addresses[].is_current | boolean | |
| phones | object[] | |
| phones[].number | string | |
| phones[].formatted | string | |
| phones[].phone_type | string | null | |
| phones[].carrier | string | null | |
| emails | string[] | |
| relatives | object[] | |
| relatives[].full_name | string | |
| relatives[].relationship_type | string | null | |
| relatives[].dob_year | string | null | |
| relatives[].current_age | integer | null | |
| civil_records | object | null | |
| civil_records.bankruptcies | integer | |
| civil_records.liens | integer | |
| civil_records.judgments | integer | |
| driver_licenses | object[] | |
| driver_licenses[].number | string | |
| driver_licenses[].state | string | null | |
| driver_licenses[].issue_date | string | null | |
| driver_licenses[].expiration_date | string | null | |
| driver_licenses[].gender | string | null | |
| driver_licenses[].race | string | null | |
| driver_licenses[].height | string | null | |
Account
| Поле | Тип | Описание |
|---|
| nickname | string | |
| balance_cents | integer | |
| available_cents | integer | balance minus reservations of running searches |
| package_requests_left | integer | |
| packages | object[] | |
| packages[].id | string | |
| packages[].name | string | |
| packages[].requests_left | integer | |
| packages[].requests_total | integer | |
| packages[].expires_at | string | |
| prices | object | your price per product/add-on, cents |
| limits | object | |
| limits.requests_per_minute | integer | |
| limits.concurrent_requests | integer | |
Коды ответов
Тело любой ошибки одинаковое: error (машиночитаемый код), message (текст), charged: false. При 429 добавляется retry_after в секундах и заголовок Retry-After.
| Код | error | Значение | Списывается запрос |
|---|
| 200 | — | Поиск выполнен: status completed (найден) или not_found (совпадений нет) | Да — состоявшийся поиск |
| 202 | — | Принят в очередь (mode: async) | Нет — спишется при выполнении |
| 401 | unauthorized | Ключа нет, он неверный, отозван или истёк | Нет |
| 402 | payment_required | Нет запросов в пакете и не хватает баланса на цену продукта | Нет |
| 403 | forbidden | IP не в списке разрешённых для ключа, либо аккаунт приостановлен | Нет |
| 404 | not_found | Неизвестный request_id | Нет |
| 409 | addon_unavailable | Докупка неприменима к этому запросу или пока не выдаётся по API | Нет |
| 422 | validation_error | Параметры не приняты: нет уточнения, ZIP в адресе, кириллица, неверная дата | Нет |
| 429 | rate_limited / too_many_running | Больше 60 запросов в минуту с аккаунта или слишком много запросов в работе | Нет |
| 503 | source_unavailable | Источник данных не ответил | Нет |
Особый случай — человек найден, но в записи нет нужного куска (SSN без полной даты рождения, DL без номера, MVR без дат). Такой ответ приходит как not_found и не оплачивается никогда.
Формат уведомления вебхука
Адрес и секрет задаются в кабинете. Уведомление — POST с JSON-телом; в теле тот же объект Request, что отдаёт GET /requests/{id}, плюс поле event. Ответ 2xx считается успешной доставкой, иначе выполняются повторы. Отвечайте быстро — таймаут 5 секунд, обработку делайте фоном.
События
- search.completed — поиск выполнен, результат готов (в том числе not_found)
- search.failed — поиск не состоялся, списания не было
- package.low — остаток запросов ниже порога из настроек уведомлений
- package.expiring — пакет скоро сгорает
Заголовки: X-Signature — подпись, X-Event — событие, X-Delivery-Id — идентификатор доставки (для дедупликации), X-Request-Id, X-Timestamp.
POST https://your-service.com/hooks/search
Content-Type: application/json
X-Signature: sha256=6b1c…f0a2
X-Event: search.completed
X-Delivery-Id: 4c1d0e9a-…
X-Request-Id: req_8f21c4
X-Timestamp: 1786901240
{
"event": "search.completed",
"request_id": "req_8f21c4",
"client_ref": "order-1187",
"product": "prod_ssn_bg",
"status": "completed",
"charged": true,
"error": null,
"finished_at": "2026-08-17T11:07:20Z",
"result": { "found": true, "matches_count": 1, "records": [ … ] }
}Проверка подписи
X-Signature — это sha256= и HMAC-SHA256 от сырого тела запроса, ключ — секрет вебхука из кабинета. Считайте HMAC по байтам тела до разбора JSON и сравнивайте константным временем.
Повторы доставки
Если ваш адрес ответил не 2xx или не ответил за 5 секунд, доставка повторяется через 1, 5, 15 и 60 минут — всего четыре попытки. Все попытки видны в кабинете, там же недоставленное можно отправить повторно вручную. После трёх подряд неудач приходит письмо. Результаты не теряются — они доступны через GET /requests/{id}.
Когда списывается запрос
Списание происходит только за состоявшийся поиск: источник ответил, и ответ передан вам. Отсутствие совпадений тоже считается состоявшимся поиском — работа выполнена. Ошибки параметров, недоступность источника, превышение лимита и отозванный ключ не списывают ничего. В ответе всегда есть поле charged и объект charge с источником списания.
Запрос из пакета — это поиск ssn_bg: сначала тратится пакет с самым ранним сроком, потом баланс по розничной цене. Продукты dl и mvr и докупки всегда списываются с баланса.
Тот же запрос (продукт и все поля совпадают) в течение 5 минут отдаётся из сохранённого ответа: cached: true, ничего не списано.
Результат хранится 90 дней (result_expires_at), затем удаляется; метаданные запроса остаются в истории.
Ограничение частоты
Ограничение одно для всех тарифов — 60 запросов в минуту с аккаунта и 8 запросов в работе одновременно. Оно не продаётся, не повышается за деньги и нужно только для того, чтобы зациклившаяся программа одного клиента не заняла очередь целиком. Текущее состояние возвращается в заголовках каждого ответа:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 34
X-Request-Id: req_8f21c4
X-Queue-Position: 3
Примеры кода
Быстрый режим на трёх языках. Ключ и адрес подставьте свои.
curl
curl -X POST https://lookupyou.com/api/v1/search \
-H "Authorization: Bearer lp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"product":"ssn_bg","first_name":"John","last_name":"Miller","hint":"1026 Maple Lane","mode":"sync"}'Python
import requests
r = requests.post(
"https://lookupyou.com/api/v1/search",
headers={"Authorization": "Bearer lp_live_YOUR_KEY"},
json={"product": "ssn_bg", "first_name": "John", "last_name": "Miller", "hint": "1026 Maple Lane"},
timeout=300,
)
data = r.json()
if r.status_code == 200 and data["status"] == "completed":
print(data["result"]["records"][0]["ssn"])
else:
print(r.status_code, data.get("error"), data.get("message"))Node.js
const res = await fetch("https://lookupyou.com/api/v1/search", {
method: "POST",
headers: { Authorization: "Bearer lp_live_YOUR_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ product: "ssn_bg", first_name: "John", last_name: "Miller", hint: "1026 Maple Lane" }),
});
const data = await res.json();
if (res.ok && data.status === "completed") console.log(data.result.records[0].ssn);
else console.log(res.status, data.error, data.message);Отложенный режим и вебхук
Отправка в очередь и проверка подписи уведомления на стороне вашего сервера.
// 1. отправка в очередь
const accepted = await fetch("https://lookupyou.com/api/v1/search", {
method: "POST",
headers: { Authorization: "Bearer lp_live_YOUR_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ product: "ssn_bg", first_name: "John", last_name: "Miller", hint: "TX", mode: "async", client_ref: "order-1187" }),
}).then((r) => r.json());
// { request_id: "req_8f21c4", status: "queued", queue_position: 3, eta_seconds: 32 }
// 2. приём вебхука (Express)
import crypto from "node:crypto";
app.post("/hooks/search", express.raw({ type: "application/json" }), (req, res) => {
const expected = "sha256=" + crypto.createHmac("sha256", WEBHOOK_SECRET).update(req.body).digest("hex");
const given = req.get("X-Signature") ?? "";
if (given.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))) return res.sendStatus(401);
const event = JSON.parse(req.body); // { event: "search.completed", request_id, client_ref, status, charged, result }
res.sendStatus(200); // ответить сразу, обработку — фоном
setImmediate(() => handle(event));
});История изменений
- v1.0 — Поиск ssn_bg / dl / mvr в режимах sync и async, докупки DL и MVR, вебхуки с подписью и повторами, история запросов, баланс и пакеты, OpenAPI-схема.