Credit Score & Skip Tracing API
combined Markdown credit score Markdown TruePeopleSearch Markdown llms.txt health OpenAPImethod_lookup API
Two APIs share one base URL and one API-key pool. Each service has its
own LLM Markdown document below.
Credit Score API
Returns an applicant's FICO score from a soft credit inquiry.
- Transport: JSON over HTTPS
- Typical duration: 95-140 seconds
- One application per person. Re-running the same identity shortly after a
completed application is rejected.
- Service prefix:
/api/apply
LLM documentation endpoints
GET /api/apply/docs.md— this document (text/markdown)GET /api/apply/llms.txt— alias of this documentGET /docs.mdandGET /llms.txt— combined documentation for both APIsGET /swagger— interactive OpenAPI UIGET /openapi.json— OpenAPI schema
TruePeopleSearch skip-tracing documentation is at /search/docs.md and
/search/llms.txt.
The Swagger UI groups this route under Credit Score. It uses the shared
ApiKeyAuth scheme (X-API-Key) in the Authorize dialog; the endpoint
also accepts Authorization: Bearer <key> for compatibility.
Authentication
Every POST /api/apply request must send the API key, either as:
x-api-key: <key>Authorization: Bearer <key>
Missing or wrong key:
401 { "success": false, "error": "Unauthorized" }
If the service itself has no key configured, it refuses to run:
503 { "success": false, "error": "API authentication is not configured" }
Public routes (no key needed): GET /, GET /docs, GET /docs.md,
GET /llms.txt, GET /health, GET /swagger, GET /openapi.json,
GET /api/apply/docs.md and GET /api/apply/llms.txt.
POST /api/apply
Runs one application and returns the score.
Request body
Required:
firstName(string)lastName(string)dob(string,MM/DD/YYYY)street(string)city(string)state(string, 2-letter code or full name)zip(string; a numeric JSON value is also accepted)
Optional:
ssn(string, 9 digits, with or without dashes) — submitted only if the
application asks for it
email(string) — generated from the name if omittedphone(string, 10 digits) — area code matched to the state if omittedflow(string,fastorui) — overrides the server'sFLOW_MODE
Response
A score was retrieved (score is an integer, 300-850; approval is a separate
matter):
200 { "success": true, "score": 764 }
The credit file is frozen, so nothing could be evaluated:
200 { "success": true, "isFrozen": true }
The application failed without a score:
502 { "success": false, "error": "Application declined" }
The time limit was exceeded:
504 { "success": false, "error": "Run exceeded 170000ms at phase \"esign\"" }
Invalid input:
400 { "success": false, "error": "Missing required fields: firstName, lastName, street, city, state, zip." }
Unexpected server failure:
500 { "success": false, "error": "Internal Server Error" }
Status codes
| Status | Meaning |
| --- | --- |
| 200 | Score retrieved, or the credit file is frozen |
| 400 | Invalid JSON, missing fields, invalid DOB, state or SSN |
| 401 | Missing or wrong API key |
| 502 | Application failed without a score |
| 503 | No API key is configured on the server |
| 504 | Run exceeded RUN_DEADLINE_MS |
The response never contains the applicant's name, address, date of birth, SSN,
email or phone. Error text is sanitized ([email], [phone], [ssn],
[date]) and capped at 200 characters.
Example
curl -s -o /tmp/apply.json -w 'HTTP %{http_code} in %{time_total}s\n' \
-X POST "$BASE_URL/api/apply" \
-H "x-api-key: $API_KEY" \
-H 'Content-Type: application/json' \
--max-time 190 \
-d '{
"firstName": "<first name>",
"lastName": "<last name>",
"dob": "<MM/DD/YYYY>",
"street": "<street>",
"city": "<city>",
"state": "<2-letter state>",
"zip": "<ZIP>",
"ssn": "<9 digits>"
}'
jq . /tmp/apply.json
Trailing slash is accepted directly: POST /api/apply/.
GET /health
200 { "status": "ok" }
Notes
success: truemeans a score was retrieved. A declined application with a
score is still success: true.
- Declines without a score return
502. Frozen files returnisFrozen: true. - A fresh identity is required for each run.
- The flow runs through a NodeMaven Scraping Browser session and closes it when
the run ends, including on failure or timeout.
RECORD_RUN=truewrites per-run artifacts underlogs/.
TruePeopleSearch Skip-Tracing API
Public-records search endpoints under /search/*, backed by TruePeopleSearch
through the NodeMaven Scraping Browser.
- Transport: JSON over HTTPS
- Authentication:
X-API-Key - Default response format:
competitor - Upstream: TruePeopleSearch
- Parsed responses are cached for
CACHE_TTL_SECONDS(default 900 seconds).
Identical concurrent requests are collapsed into one upstream fetch.
LLM documentation endpoints
GET /search/docs.md— this document (text/markdown)GET /search/llms.txt— alias of this documentGET /docs.mdandGET /llms.txt— combined documentation for both APIsGET /swagger— interactive OpenAPI UIGET /openapi.json— OpenAPI schema
Credit-score documentation is at /api/apply/docs.md and
/api/apply/llms.txt.
The Swagger UI groups these routes under TruePeopleSearch. They use the
shared ApiKeyAuth scheme (X-API-Key) in the Authorize dialog.
Authentication
Every /search/* data endpoint requires the API key in the X-API-Key header:
curl -H "X-API-Key: $API_KEY" \
"$BASE_URL/search/byname?name=John%20Smith&page=1"
Authorization: Bearer <key> is accepted by POST /api/apply, not by the
/search/* endpoints.
Missing or wrong key:
401 { "detail": "Invalid or missing API key" }
The response includes WWW-Authenticate: ApiKey.
If the service itself has no key configured:
503 { "detail": "API authentication is not configured" }
Common query parameters
Every data endpoint accepts:
format=competitor(default) — competitor-compatible envelopeformat=native— native TruePeopleSearch envelope
Endpoints with pagination accept page (integer, minimum 1, default 1).
Invalid format or page values are rejected by request validation with
HTTP 422.
Trailing slashes are accepted directly, for example /search/byname/ and
/search/detailsbyID/.
Endpoints
| Endpoint | Required parameters | Pagination |
| --- | --- | --- |
| GET /search/byname | name | page |
| GET /search/byaddress | street, citystatezip | page |
| GET /search/bynameaddress | name, citystatezip | page |
| GET /search/byphone | phoneno | page |
| GET /search/byemail | email | no |
| GET /search/detailsbyID | peo_id | no |
Search by name
curl -H "X-API-Key: $API_KEY" \
"$BASE_URL/search/byname?name=John%20Smith&page=1"
Search by address
curl -H "X-API-Key: $API_KEY" \
"$BASE_URL/search/byaddress?street=1%20Main%20St&citystatezip=Austin%2C%20TX&page=1"
Search by name and city/state/ZIP
curl -H "X-API-Key: $API_KEY" \
"$BASE_URL/search/bynameaddress?name=John%20Smith&citystatezip=Austin%2C%20TX&page=1"
Search by phone
curl -H "X-API-Key: $API_KEY" \
"$BASE_URL/search/byphone?phoneno=5125550100&page=1"
Search by email
curl -H "X-API-Key: $API_KEY" \
"$BASE_URL/search/byemail?email=jane%40example.com"
Person details by ID
curl -H "X-API-Key: $API_KEY" \
"$BASE_URL/search/detailsbyID?peo_id=p123"
Missing parameters
Missing required query parameters return HTTP 200 with the legacy error
envelope, not 400:
{"error": "name parameter Not found"}
| Endpoint | Competitor error | Native Message |
| --- | --- | --- |
| /search/byname | name parameter Not found | name parameter Not found |
| /search/byaddress | street and citystatezip parameter Not found | street, citystatezip parameter Not found |
| /search/bynameaddress | name and address parameter Not found | name, citystatezip parameter Not found |
| /search/byphone | phone parameter Not found | phoneno parameter Not found |
| /search/byemail | email parameter Not found | email parameter Not found |
| /search/detailsbyID | peo_id parameter Not found | peo_id parameter Not found |
The native missing-parameter envelope is:
{
"Status": 200,
"Source": "_cch_dch",
"Message": "name parameter Not found",
"Records": 0,
"Page": 1,
"PropertyDetails": {},
"PeopleDetails": []
}
Competitor response format (default)
Search
{
"Status": 200,
"Message": "state_1; Use the /person_details_by_ID endpoint to gather more info!",
"Source": "ncch_dch",
"Records": 1,
"Page": 1,
"PropertyDetails": {},
"PeopleDetails": [
{
"Name": "Jane Q Example",
"Link": "https://www.truepeoplesearch.com/find/person/p123",
"Person ID": "p123",
"Age": "42",
"Lives in": "Austin, TX",
"Used to live in": "1 Old St, Austin, TX 78701, 2 Older St, Austin, TX 78702",
"Related to": "Alex Example, Sam Example",
"peo_id": "p123",
"Used_Names": ["J Q Example"],
"Previous_Addresses": [
"1 Old St, Austin, TX 78701",
"2 Older St, Austin, TX 78702"
],
"Related": ["Alex Example", "Sam Example"]
}
]
}
When no records are found:
{
"Status": 200,
"Message": "state_1; We could not find any records for that search criteria",
"Source": "ncch_dch",
"Records": 0,
"Page": 1,
"PropertyDetails": {},
"PeopleDetails": []
}
Records is the total record count reported by TruePeopleSearch when
available, otherwise the number of returned records. Page echoes the
requested page.
Details
{
"Status": 200,
"Message": "state_1",
"Source": "ncch_dch",
"Person Details": [
{
"Person_name": "Jane Q Example",
"Age": "42",
"Born": "January 1980",
"Lives in": "Austin, TX",
"Telephone": "(512) 555-0100"
}
],
"Current Address Details List": [
{
"street_address": "1 Old St",
"address_locality": "Austin",
"address_region": "TX",
"postal_code": "78701",
"county": "Travis County",
"date_range": "(Jan 2020 - Jan 2026)",
"property_summary": "$100,000 | 3 Bed"
}
],
"All Phone Details": [
{
"phone_number": "(512) 555-0100",
"phone_type": "Wireless",
"phone_info": "Possible Primary Phone",
"last_reported": "Last reported Jan 2026",
"provider": "Example Wireless",
"status": "Active"
}
],
"Email Addresses": ["jane@example.com"],
"Previous Address Details": [],
"All Relatives": [
{
"Name": "Alex Example",
"Age": "30",
"Person Link": "https://www.truepeoplesearch.com/find/person/p456",
"Person ID": "p456",
"Relationship": "Sibling"
}
],
"All Associates": [],
"Records": 1,
"Page": 1,
"PropertyDetails": {},
"PeopleDetails": ["<native detail record>"],
"peo_id": "p123",
"AKAs": ["J Q Example"],
"Phone_Numbers": ["(512) 555-0100"],
"All_Addresses": ["1 Old St, Austin, TX 78701"],
"Property_Details": {
"Bedrooms": "3",
"Bathrooms": "2",
"Sq_Ft": "1500",
"Year_Built": "1985",
"Estimated_Value": "$100,000",
"Estimated_Equity": "$50,000",
"Last_Sale_Amount": "$80,000",
"Last_Sale_Date": "Jan 2020",
"Occupancy": "Owner",
"Ownership": "Individual",
"Type": "Single Family",
"Class": "Residential",
"Subdivision": "Example",
"Lot_Sq_Ft": "5000",
"APN": "000-000-000",
"School_District": "Example ISD",
"Address": "1 Old St, Austin, TX 78701"
},
"Possible_Relatives": ["Alex Example"],
"Possible_Associates": []
}
If the details adapter receives no records, it returns:
{
"Status": 200,
"Source": "_cch_dch",
"Message": "peo_id Not Valid",
"Records": 0,
"PeopleDetails": []
}
Competitor key mapping
| Competitor key | Source field |
| --- | --- |
| Person ID | peo_id |
| Lives in | Lives_In |
| Used to live in | Previous_Addresses joined with , |
| Related to | Related joined with , |
| Person Details | Name, Age, Born, Lives_In, first phone |
| Current Address Details List | Current_Address_Details |
| All Phone Details | Phone_Details |
| Email Addresses | Emails |
| Previous Address Details | Previous_Address_Details |
| All Relatives | Relatives_Details |
| All Associates | Associates_Details |
Additive extras retained for existing clients: peo_id, Used_Names,
Previous_Addresses, Related, Records, Page, PropertyDetails,
PeopleDetails, AKAs, Phone_Numbers, All_Addresses, Property_Details,
Possible_Relatives, Possible_Associates, property_summary, status and
Relationship.
Native response format (format=native)
Search
{
"Status": 200,
"Source": "ncch_dch",
"Message": "Successful Search Result",
"Records": 1,
"Page": 1,
"PropertyDetails": {},
"PeopleDetails": [
{
"peo_id": "p123",
"Name": "Jane Q Example",
"Age": "42",
"Lives_In": "Austin, TX",
"Previous_Addresses": [],
"Related": []
}
]
}
Details
The native details response uses the same envelope with one record:
{
"Status": 200,
"Source": "ncch_dch",
"Message": "Successful Search Result",
"Records": 1,
"Page": 1,
"PropertyDetails": {},
"PeopleDetails": ["<native detail record>"]
}
Errors
| Status | Body | Meaning |
| --- | --- | --- |
| 200 | Legacy missing-parameter envelope | A required query parameter is empty or absent |
| 401 | {"detail": "Invalid or missing API key"} | Missing or wrong key |
| 422 | FastAPI validation details | Invalid format or page |
| 500 | {"detail": "Unable to retrieve data from the source. Please try again later."} | Upstream or NodeMaven failure |
| 503 | {"detail": "API authentication is not configured"} | No server API key configured |
Upstream details are logged server-side only. The client-facing 500 body never
contains proxy URLs, NodeMaven tokens, attempt counts or upstream HTML.
Notes
- The
Sourcekey is preserved for compatibility; its value is an internal
cache indicator, not a copy of the competitor value.
- The upstream is scraped through a warm, auto-scaling NodeMaven session pool.
Pool size, session TTL, retries and cache TTL are configured through
environment variables.
- Response sets are not guarantees of identity; treat public-records matches
as candidates and verify them.