One-request quickstart API v2

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

Send a unique 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/HTTP
POST /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/HTTP
HTTP/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

The configured product-4 credit price is charged once per applicant. The request is rejected with 402 Payment Required before anything is created if the balance cannot cover the whole batch.

Previous address is optional

Always provide 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

  • 400 malformed values or unsupported fields, including Product
  • 401 missing or invalid API key
  • 402 insufficient credits for the whole batch
  • 409 the ReferenceId was already used with different details
  • 422 missing or semantically invalid fields, returned with indexed paths
  • 500 creation failed; retry the exact payload with the same ReferenceId

422 response: indexed validation error

JSON/HTTP
HTTP/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

Send a unique 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/HTTP
POST /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": true to include sanctions screening.
  • If ExtraChecks is 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/HTTP
POST /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

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/HTTP
export 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/HTTP
export 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"