Start here
Quickstart
Three requests take you from a new key to a finished credit report. Set your key as an environment variable first so it never ends up in your code: export TGR_API_KEY=sk_live_.... For each new order, generate a unique retry key too: export TGR_IDEMPOTENCY_KEY=....
1. See what you can order
GET /products/ lists every product your company can order, with the price that applies to you. Each product value is also the path you order it from.
curl https://api.thegreatrenter.com/api/v1/products/ \
-H "X-Api-Key: $TGR_API_KEY"{
"data": [
{
"product": "identity_verification",
"name": "Identity Verification (OneID)",
"kind": "check",
"price": "<your price>",
"currency": "CAD"
}
]
}2. Order a check
Send the applicant to the product's endpoint. This example orders an Equifax credit report. The response comes back straight away with a reference; the report itself follows when the bureau responds.
curl -X POST https://api.thegreatrenter.com/api/v1/credit_check/ \
-H "X-Api-Key: $TGR_API_KEY" \
-H "Idempotency-Key: $TGR_IDEMPOTENCY_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "jane.doe@example.com",
"first_name": "Jane",
"middle_name": "Q",
"last_name": "Doe",
"date_of_birth": "1990-05-01",
"sex": "F",
"birth_place": { "country": "CA", "city": "Toronto", "province": "ON" },
"residences": [
{
"street_address": "1 King St W",
"unit": "1200",
"city": "Toronto",
"province": "ON",
"country": "CA",
"postal_code": "M5H1A1",
"start_date": "2022-06-01"
}
]
}'{
"reference": "TGR_CA_1A2B3C4D5",
"product": "credit_check",
"status": "in_progress",
"message": null,
"payment_status": "paid",
"amount": "<your price>",
"currency": "CAD",
"applicant": { "name": "Jane Q Doe", "email": "jane.doe@example.com" },
"report": null,
"created_at": "2026-07-03T12:00:00Z",
"completed_at": null
}3. Fetch the result
Poll the order by its reference until status is completed, or skip polling entirely and subscribe a webhook. For a credit report, the normalized result is in credit.
curl https://api.thegreatrenter.com/api/v1/credit_check/TGR_CA_1A2B3C4D5/ \
-H "X-Api-Key: $TGR_API_KEY"Authentication
Every product endpoint takes an API key in the X-Api-Key header. Keys belong to your company and look like sk_live_xxxx or sk_test_xxxx. API keys and webhook endpoints are managed from your company dashboard on app.thegreatrenter.com; if you don't have an account yet, start here.
- Scopes. Placing an order needs a key with
WRITEorREAD_WRITEscope. Read endpoints accept a key of any scope, so give reporting jobs a read-only key. - IP allowlist. If your company has an allowlist configured, requests from any other address are refused.
- Failures. A missing, invalid, or inactive key returns
401. The wrong scope or an IP that is not allowlisted returns403.
Keep keys on the server
Endpoints
All paths are relative to https://api.thegreatrenter.com/api/v1. Each product has the same three routes: order, list, and get one. Order bodies can be sent as JSON, form data, or URL-encoded. Every order route also accepts an optional Idempotency-Key header for safe retries.
| Method | Path | What it does |
|---|---|---|
| GET | /products/ | Products you can order, with your price and currency. |
| POST | /credit_check/ | Order Credit Report. |
| GET | /credit_check/ | List your Credit Report orders, newest first. |
| GET | /credit_check/{reference}/ | One Credit Report order and its result. |
| POST | /identity_verification/ | Order Identity Verification. |
| GET | /identity_verification/ | List your Identity Verification orders, newest first. |
| GET | /identity_verification/{reference}/ | One Identity Verification order and its result. |
| POST | /global_watchlist/ | Order Global Watchlist. |
| GET | /global_watchlist/ | List your Global Watchlist orders, newest first. |
| GET | /global_watchlist/{reference}/ | One Global Watchlist order and its result. |
| POST | /adverse_media/ | Order Adverse Media. |
| GET | /adverse_media/ | List your Adverse Media orders, newest first. |
| GET | /adverse_media/{reference}/ | One Adverse Media order and its result. |
| POST | /basic_screening/ | Order Basic Screening. |
| GET | /basic_screening/ | List your Basic Screening orders, newest first. |
| GET | /basic_screening/{reference}/ | One Basic Screening order and its result. |
| POST | /enhanced_screening/ | Order Enhanced Screening. |
| GET | /enhanced_screening/ | List your Enhanced Screening orders, newest first. |
| GET | /enhanced_screening/{reference}/ | One Enhanced Screening order and its result. |
| POST | /identity_verification/{reference}/review/ | Approve, decline, or ask for a resubmission on a verification in review. |
Packages. basic_screening runs the Standard bundle and enhanced_screening the Complete bundle in a single order. Their identity step uses a document check on ID images you supply, not the hosted selfie flow of the standalone identity verification.
The applicant
Order endpoints share the applicant fields below. Dates are YYYY-MM-DD. Five fields are always required: email, first_name, middle_name, last_name, and date_of_birth. Send an empty string for middle_name when the applicant has none; the applicant must be 18 to 120 years old. Residences are also required except for standalone identity verification using oneId_1. The example in the quickstart shows a complete body.
| Field | Type | Description |
|---|---|---|
first_namerequired | string | Legal first name. |
middle_namerequired | string | Middle name or initial; send an empty string when there is none. |
last_namerequired | string | Legal last name. |
emailrequired | string | The applicant's email address. |
date_of_birthrequired | date | The applicant's date of birth; they must be 18 to 120 years old. |
residences | array | Required for every product except standalone identity verification on oneId_1. See the residence fields below. |
phone_number | string | The applicant's phone number. |
sex | string | For example F. |
birth_place | object | country, province and city. |
identification | object | Packages only. ID image URLs to verify at order time; see below. |
Residences
| Field | Type | Description |
|---|---|---|
street_addressrequired | string | Street number and name. |
unit | string | Unit or apartment number. |
cityrequired | string | City. |
provincerequired | string | For example ON. |
countryrequired | string | For example CA. |
postal_coderequired | string | For example M5H1A1. |
start_daterequired | date | When the applicant moved in. |
Residence rules
start_date can never be in the future and no two residences may have the same start date. Where residences are required, the history as a whole must cover at least six months: the oldest start_date must be more than six months ago, but the current residence may be recent. The latest start date identifies the current address; each earlier residence ends when the next one starts. A body that breaks these rules returns 400. The one exception is identity verification on oneId_1, which can omit residences.Identification (packages)
Add an identification object to a basic_screening or enhanced_screening order to include a document check: a front_url (required), an optional back_url, and an optional document_type. The images are verified when you order, and an IDENTITY_VERIFICATION check is added to the report. If the images can't be read, the order stops at action_required with a message saying what to fix; order again with a clearer image.
Orders and results
Creating and fetching return an order object; list endpoints wrap those objects in a paginated response. Standalone identity verification adds one_id_url, link_expires_at, and identity_verification. Save the reference: it's how you fetch the result and how webhooks identify the order.
| Field | Type | Description |
|---|---|---|
reference | string | The order's ID, for example TGR_CA_1A2B3C4D5. |
product | string | Which product was ordered, for example credit_check. |
status | string | Where the order is; see the statuses below. |
message | string | null | A plain-language explanation when the order needs attention or could not be completed. |
payment_status | string | pending, invoiced, paid, or failed. |
amount, currency | string | What the order cost, and in which currency. |
applicant | object | The applicant's name and email. |
report | array | null | Check-level results, one entry per case: id, created, overall_status, overall_score, and a checks array of type, status, score, sub_score and output_claims. |
credit | object | null | Credit orders and packages: the normalized credit result, described below. Null until the bureau returns the report. |
created_at, completed_at | date-time | When the order was placed and when it finished. |
Statuses
Product orders use pending while payment is being taken, action_required while being submitted or waiting for corrected input, and in_progress while the provider is working. They finish as completed or failed. Only completed carries a final result; read message whenever attention is required. The invited, opened, started, and payment_required values belong to the dashboard flow and are not used for product orders. Treat an unrecognised future value as still processing.
The credit object
The bureau is picked from the applicant's most recent address, and credit has the same shape wherever they live. Scales differ by region, so read score_range instead of assuming 300 to 900. When the bureau returns an itemised file, credit.detail holds it in sections; each section lists its own columns, so read those rather than hard-coding field names, and treat an empty rows array as nothing reported.
"credit": {
"bureau": "equifax_us",
"country": "US",
"status": "COMPLETE",
"score": 710,
"score_range": { "min": 300, "max": 850 },
"band": "GOOD",
"date_created": "2026-07-03T12:19:00Z",
"claims": { "credit_score": 710, "has_bankruptcies": false }
}Safe retries
Give every new order a unique Idempotency-Key of at most 255 characters, such as a UUID. Retrying the same body with the same key creates no duplicate and returns the original order with 200 and Idempotent-Replayed: true. Reusing the key with a different body returns 409. Keys are scoped to your company and do not expire, so use a new value for each intended order. Without this header, every retry places a new order.
Billing
Every order is priced for your company. On PAY_PER_CHECK billing the card is charged when you order and refunded automatically if the provider rejects the order, so you only pay for orders that succeed; a declined card returns 402. On INVOICE_MONTHLY the order is added to your monthly invoice.
Identity verification
A standalone identity verification works differently from the other checks, because the applicant has to take part: they upload a government ID and complete a selfie and liveness check on a page the provider hosts.
POST /identity_verification/returns aone_id_url, valid for 14 days (link_expires_at).- You send that link to the applicant. The Great Renter does not email them, and the order stays
in_progressuntil they finish. - When they do,
identity_verificationon the order holds the outcome in the same shape for every provider:status(verified,in_review,failedorpending),result,is_identity_verified, the extracted name, date of birth and document details, and anywarnings.
To pick the provider for one order, send the optional X-IDV-Provider header as oneId_1 or oneId_2. Without it, your company's configured provider is used. oneId_2 matches against address history, so it needs residences; oneId_1 does not.
Status-only identity results
identity_verification returns only the provider, status, result, verification flag, warnings, review or failure reason, and resubmission_options. Applicant names, dates of birth, document details, and images are omitted from API responses and webhooks.Reviewing a result
When a verification comes back in_review, record a decision with POST /identity_verification/{reference}/review/. Every request needs a decision and an actor, your identifier for the person deciding, such as their email.
| Field | Type | Description |
|---|---|---|
approve | decision | Closes the order as completed; the status becomes verified. |
decline | decision | Closes the order as completed; the status becomes failed. |
resubmit | decision | Reopens the order as in_progress with status pending. Send the applicant the returned one_id_url. |
corrections | object | Optional on any decision, to fix a misread document field: given_name, family_name, date_of_birth, document_type (P, ID, DL, RP or SSC) and document_number. The applicant record itself is never changed. |
resubmit_nodes | array | Optional only with resubmit. Pass retry targets from the result's resubmission_options, or omit it to retry all eligible steps automatically. |
POST /api/v1/identity_verification/TGR_CA_1A2B3C4D5/review/
X-Api-Key: <your write-capable API key>
Content-Type: application/json
{
"decision": "approve",
"actor": "admin@example.com",
"comment": "Identity confirmed."
}A decision can only be made once. 200 returns the updated order; store it. 409 means the order is no longer in review, so fetch it again. Every successful decision is logged with the actor, the API key, the time, and the result before and after.
Webhooks
Register an endpoint URL, subscribe it to events, and The Great Renter POSTs a signed payload to it when a matching order finishes. Endpoints are managed from your company dashboard by the account owner or an admin; the signing secret is shown once, when the endpoint is created, so store it straight away.
| Event | Fires when |
|---|---|
| credit_check.completed | A Credit Report order finishes. |
| identity_verification.completed | A Identity Verification order finishes. |
| global_watchlist.completed | A Global Watchlist order finishes. |
| adverse_media.completed | A Adverse Media order finishes. |
| basic_screening.completed | A Basic Screening package finishes. |
| enhanced_screening.completed | A Enhanced Screening package finishes. |
Delivery
- An HTTP
POSTwithContent-Type: application/jsonand anX-Signatureheader, to every active endpoint subscribed to the event. - Respond with any
2xxwithin 10 seconds. Acknowledge first and do the heavy work asynchronously. - A non-
2xx, a timeout, or a connection error marks the attempt failed. - The endpoint URL must be publicly reachable; private, loopback and internal addresses are rejected.
Each event is delivered once
reference can safely be processed twice) and, if your receiver was down, reconcile by fetching the order from the API.Verifying the signature
X-Signature is a hex-encoded HMAC-SHA256 of the raw request body, keyed by your endpoint secret. Recompute it over the exact bytes you received, before any JSON parsing, and compare in constant time.
import crypto from "node:crypto";
import express from "express";
const app = express();
// Keep the raw bytes: the signature is computed over the body exactly as sent.
app.post("/webhooks/tgr", express.raw({ type: "application/json" }), (req, res) => {
const expected = crypto
.createHmac("sha256", process.env.TGR_WEBHOOK_SECRET)
.update(req.body)
.digest("hex");
const received = req.get("X-Signature") ?? "";
const valid =
received.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
if (!valid) return res.sendStatus(401);
const event = JSON.parse(req.body.toString("utf8"));
queue.add(event); // process later; answer within 10 seconds
res.sendStatus(200);
});Payload
A <product>.completed event carries the order's reference, status, completed_at and report, plus credit for credit results. For identity_verification.completed, an identity_verification object takes the place of credit.
{
"event": "credit_check.completed",
"reference": "TGR_CA_1A2B3C4D5",
"status": "completed",
"completed_at": "2026-07-03T12:20:00Z",
"report": [
{ "id": "case-abc", "overall_status": "COMPLETE", "checks": ["..."] }
],
"credit": {
"bureau": "equifax_us",
"country": "US",
"status": "COMPLETE",
"score": 710,
"score_range": { "min": 300, "max": 850 },
"band": "GOOD",
"date_created": "2026-07-03T12:19:00Z",
"claims": { "credit_score": 710, "has_bankruptcies": false }
}
}Errors, limits and pagination
| Status | Meaning |
|---|---|
| 400 | Validation error: missing or invalid applicant data, residence history, review data, or idempotency key. |
| 401 | API key is missing, invalid, or inactive. |
| 402 | Payment failed, for example a declined card or no payment method on file. |
| 403 | API key lacks the required scope, or the request IP is not allowlisted. |
| 404 | No such order for your company, or a requested list page is past the final page. |
| 409 | An idempotency key was reused with a different body, or a verification is no longer available for review. |
| 429 | Rate limit exceeded. For API-key limits, wait the number of seconds in Retry-After; review-provider throttling may require fetching the order before retrying. |
| 502 | Identity review only: the verification service could not confirm the decision. Fetch the order before retrying. |
Rate limits
Limits apply per API key and are counted across every product endpoint: 2,000 reads an hour and 120 orders an hour. Exceeding either returns 429 with a Retry-After header giving the seconds to wait before retrying.
Pagination
List endpoints return orders newest first, a page at a time, as count, totalPages, currentPage, and data. Pass page and limit to page through; the default limit is 10 and the maximum is 100. A page past the end returns 404. Use search for a partial, case-insensitive match on reference, applicant name, or email; reference and email for exact case-insensitive matches; and status for one or more comma-separated statuses. Filters combine with AND. ordering selects the result order.
Ready to build?
Keys are issued to company accounts. Email us with what you're building, read how pricing and access work, or try requests in the interactive Swagger reference.