We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Run credit checks in one request
Send the tenancy and details for 1–6 applicants once, then follow the existing webhook and report flow.
Run 1–6 credit checks in one request
For a credit-only workflow, call
POST /api/v2/credit-checks
with the tenancy, each applicant's basic details, current address, and optional previous address. Lets Safe creates the reference, completes the supplied applicant details, selects product 4, and starts every credit check. No applicant invite is sent.
One ReferenceId per batch
ReferenceId
(GUID) from your system. An exact retry returns the existing reference and applicant IDs without charging again. Reusing the ID with different details returns
409 Conflict
.
Request: create and start credit checks
JSON/HTTPPOST /api/v2/credit-checks
Content-Type: application/json
apikey: YOUR_API_KEY
{
"ReferenceId": "123e4567-e89b-12d3-a456-426614174000",
"TenancyAddressLine1": "10 Example Street",
"TenancyAddressLine2": "Flat 2",
"TenancyAddressTown": "London",
"TenancyAddressCounty": "Greater London",
"TenancyAddressPostcode": "SW1A 1AA",
"TenancyMonthlyRent": 1500,
"TenancyStartDate": "2026-10-01",
"TenancyTerm": 12,
"Applicants": [
{
"ApplicantTitleId": 1,
"ApplicantFirstName": "Alex",
"ApplicantLastName": "Morgan",
"ApplicantDateOfBirth": "1990-04-12",
"ApplicantEmailAddress": "alex.morgan@example.com",
"ApplicantPhoneNumber": "07123456789",
"TenantShareOfRent": 750,
"CurrentAddress": {
"HouseName": "22 Current Road",
"Postcode": "M1 1AE",
"MovedInOn": "2022-06-01",
"ResidentialStatusId": 1
},
"PreviousAddress": {
"HouseName": "5 Previous Avenue",
"Postcode": "B1 1BB",
"MovedInOn": "2018-03-01",
"MovedOutOn": "2022-05-31",
"ResidentialStatusId": 2
}
}
]
}
202 response: accepted for processing
JSON/HTTPHTTP/1.1 202 Accepted
{
"Result": true,
"Id": 12345,
"ReferenceId": "123e4567-e89b-12d3-a456-426614174000",
"Applicants": [
{
"ApplicantId": "84ee9aa2-d652-5dbc-941b-bb9bb21370cf",
"Status": "Accepted"
}
],
"Error": null,
"ValidationMessages": []
}
Asynchronous processing
A
202 Accepted
response means the complete batch was saved atomically. It does not mean the provider has finished. Each applicant has one of these immediate scheduling states:
-
Accepted— the credit job is durably queued, a result already exists, or the workflow reached a terminal outcome. This does not mean the provider passed the applicant. -
Pending— the applicant is safely stored and the grading runner will retry after an operational dependency becomes available.
Wait for the
applicant/completed
webhook, or poll
GET /api/v2/applicants/:applicant_id
. You can then retrieve structured results or the final PDF from the report endpoints.
Credit usage
402 Payment Required
before anything is created if the balance cannot cover the whole batch.
Previous address is optional
CurrentAddress
. You may omit
PreviousAddress
; when you include it, supply every previous-address field. Existing provider behaviour prefers the previous address for its search.
Errors and safe retries
-
400malformed values or unsupported fields, includingProduct -
401missing or invalid API key -
402insufficient credits for the whole batch -
409theReferenceIdwas already used with different details -
422missing or semantically invalid fields, returned with indexed paths -
500creation failed; retry the exact payload with the sameReferenceId
422 response: indexed validation error
JSON/HTTPHTTP/1.1 422 Unprocessable Entity
{
"Result": false,
"Id": null,
"ReferenceId": null,
"Applicants": [],
"Error": "Validation failed",
"ValidationMessages": [
{
"Path": "Applicants[0].CurrentAddress.Postcode",
"Messages": ["must be a valid UK postcode"]
}
]
}
Full and multi-step references
Keep using
POST /api/v2/references
when you need full referencing, applicant invitations, per-applicant product selection, extra checks, or the existing
/api/v2/reference/steps/*
flow. These endpoints remain available for backward compatibility.
Idempotency with ReferenceId
ReferenceId
(GUID) from your system to make retries safe. If you retry with the same
ReferenceId
, Lets Safe returns the existing reference and applicants without double-charging credits.
Request: create reference
JSON/HTTPPOST /api/v2/references
Content-Type: application/json
apikey: YOUR_API_KEY
{
"ReferenceId": "123e4567-e89b-12d3-a456-426614174000",
"TenancyAddressLine1": "123 Example Street",
"TenancyAddressTown": "London",
"TenancyAddressCounty": "Greater London",
"TenancyAddressPostcode": "SW1A 1AA",
"TenancyMonthlyRent": 1500,
"TenancyStartDate": "2025-09-01T00:00:00Z",
"Applicants": [
{
"ApplicantFirstName": "Alex",
"ApplicantLastName": "Taylor",
"ApplicantEmailAddress": "alex.taylor@example.com",
"ApplicantPhoneNumber": "07700900000",
"Product": 4,
"TenantShareOfRent": 1500
}
]
}
Response: create reference
JSON/HTTP{
"Result": true,
"Id": "123e4567-e89b-12d3-a456-426614174000",
"ApplicantIds": [
"987fcdeb-51a2-43d1-b789-123456789abc"
],
"Error": null,
"ValidationMessages": []
}
Optional ExtraChecks
You can request additional screening by including
ExtraChecks
on each applicant in
POST /api/v2/references
and when adding guarantors with
POST /api/v2/applicants/:applicant_id/gtors/add
.
-
Set
"Sanctions": trueto include sanctions screening. -
If
ExtraChecksis omitted (or"Sanctions": false), no sanctions check is requested. - Unrecognised keys are ignored.
Request snippet: applicant with ExtraChecks
JSON/HTTP{
"ReferenceId": "123e4567-e89b-12d3-a456-426614174000",
"Applicants": [
{
"ApplicantFirstName": "Alex",
"ApplicantLastName": "Taylor",
"ApplicantEmailAddress": "alex.taylor@example.com",
"ApplicantPhoneNumber": "07700900000",
"Product": 4,
"TenantShareOfRent": 1500,
"ExtraChecks": {
"Sanctions": true
}
}
]
}
Request snippet: guarantor with ExtraChecks
JSON/HTTPPOST /api/v2/applicants/:applicant_id/gtors/add
Content-Type: application/json
apikey: YOUR_API_KEY
{
"ApplicantFirstName": "Jamie",
"ApplicantLastName": "Guarantor",
"ApplicantEmailAddress": "jamie.guarantor@example.com",
"ApplicantPhoneNumber": "07000000001",
"ExtraChecks": {
"Sanctions": true
}
}
Product IDs
Set
Product
per applicant to control the checks performed.
| Product | Meaning | Typical use |
|---|---|---|
| 1 | Full reference | Credit + affordability + references |
| 4 | Credit check | Credit-only workflow |
| 3 | Guarantor | Add a guarantor reference |
| 5 | Guarantor credit check | Credit-only guarantor |
Get the applicant link
Use
GET /api/v2/applicants/:applicant_id/link
to fetch the hosted referencing link (for SMS, in-app messages, or embeds).
cURL: get applicant link
JSON/HTTPexport LETS_SAFE_BASE_URL="https://portal.letssafe.com"
# Sandbox: https://sandbox.letssafe.com
export LETS_SAFE_API_KEY="YOUR_API_KEY"
export APPLICANT_ID="987fcdeb-51a2-43d1-b789-123456789abc"
curl -H "apikey: $LETS_SAFE_API_KEY" \
"$LETS_SAFE_BASE_URL/api/v2/applicants/$APPLICANT_ID/link"
Resend (or update) the invite email
If an applicant needs the email re-sent (or you need to change the email address first), call
POST /api/v2/applicants/:applicant_id/email
.
cURL: resend invite email
JSON/HTTPexport LETS_SAFE_BASE_URL="https://portal.letssafe.com"
# Sandbox: https://sandbox.letssafe.com
export LETS_SAFE_API_KEY="YOUR_API_KEY"
export APPLICANT_ID="987fcdeb-51a2-43d1-b789-123456789abc"
curl -X POST \
-H "apikey: $LETS_SAFE_API_KEY" \
-H "content-type: application/json" \
-d '{ "EmailAddress": "alex.taylor@example.com" }' \
"$LETS_SAFE_BASE_URL/api/v2/applicants/$APPLICANT_ID/email"