# Immigration status

> `POST https://checksharecode.co.uk/api/check/immigration-status` checks a person's UK immigration status on gov.uk, for a bank, lender, university, council or anyone else who needs it. Everything you send to this endpoint is here, and only that. A live check usually takes 15 to 40 seconds, so set your timeout to at least 60 seconds, or use the async endpoint.

Base URL: `https://checksharecode.co.uk` · Auth: `authorization: Bearer <key>` · Web version: https://checksharecode.co.uk/docs/api/immigration-status

Synchronous: `POST https://checksharecode.co.uk/api/check/immigration-status`. Asynchronous: `POST https://checksharecode.co.uk/api/check/immigration-status/async`.

## What you send

### Synchronous

- `Authorization` (header, string, required): Bearer followed by your key. `rtw_test_…` keys return sandbox data. `rtw_live_…` keys run a real check. Example: `Bearer rtw_live_…`
- `share_code` (string, required): The 9-character code the person made at gov.uk/view-prove-immigration-status. These codes start with S; a right to work or right to rent code won’t open this check. Spaces and lower case are fine: we remove spaces and upper-case it. Example: `AB1CD2EF3`
- `date_of_birth` (string, required): The applicant's date of birth as YYYY-MM-DD. It must match the share code, and they must be at least 16. Example: `1990-01-01`
- `company_name` (string, required): Your organisation's name, 1 to 200 characters. gov.uk asks you to include your local office or branch name, and records it as the organisation making the check. Example: `Example Bank, Leeds branch`
- `job_title` (string, required): The job title of the person making the check, 1 to 200 characters. gov.uk records it on the check. Example: `Account opening officer`
- `purpose` (string, required): Why you are checking, as gov.uk asks: one of `driving_licence`, `student_loan`, `education_or_training`, `health_insurance_card`, `personal_finance`, `homelessness_or_council_housing`, `travel`, `other`. gov.uk records its own words for it, which come back in `purpose`. Example: `personal_finance`
- `other_purpose` (string): Your reason, 1 to 200 characters. Required when `purpose` is `other`, and refused otherwise. Example: `Eligibility for a hardship grant`

gov.uk shows a status rather than a yes or no, so `outcome` is always `ACCEPTED` and the answer is in `status`, `valid_until`, `activities` and `restrictions`; see [the fields](https://checksharecode.co.uk/docs/api/check.md#immigration-status-fields). Don’t send `checker_type`: it is for right to rent, and is refused here with `400 INVALID_INPUT`. You don’t need `check` either. If you send it, it must be `immigration_status`.

Save the photo and PDF if you need a record: we keep a copy of the check for up to 7 days only to investigate problems, then delete it.

cURL:

```bash
curl https://checksharecode.co.uk/api/check/immigration-status \
  -H "authorization: Bearer $CHECKSHARECODE_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "share_code": "AB1CD2EF3",
    "date_of_birth": "1990-01-01",
    "company_name": "Example Bank, Leeds branch",
    "job_title": "Account opening officer",
    "purpose": "personal_finance"
  }'
```

Node.js:

```js
const res = await fetch('https://checksharecode.co.uk/api/check/immigration-status', {
  method: 'POST',
  headers: {
    authorization: `Bearer ${process.env.CHECKSHARECODE_API_KEY}`,
    'content-type': 'application/json',
  },
  body: JSON.stringify({
    share_code: 'AB1CD2EF3',
    date_of_birth: '1990-01-01', // YYYY-MM-DD
    company_name: 'Example Bank, Leeds branch',
    job_title: 'Account opening officer',
    purpose: 'personal_finance',
  }),
});

const result = await res.json();
if (!res.ok) throw new Error(`${result.error.code}: ${result.error.message}`);
console.log(result.status); // e.g. "Settled status, also known as indefinite leave to remain"
```

Python:

```python
import os
import requests

res = requests.post(
    "https://checksharecode.co.uk/api/check/immigration-status",
    headers={"authorization": f"Bearer {os.environ['CHECKSHARECODE_API_KEY']}"},
    json={
        "share_code": "AB1CD2EF3",
        "date_of_birth": "1990-01-01",  # YYYY-MM-DD
        "company_name": "Example Bank, Leeds branch",
        "job_title": "Account opening officer",
        "purpose": "personal_finance",
    },
    timeout=60,
)
result = res.json()
if not res.ok:
    raise RuntimeError(f"{result['error']['code']}: {result['error']['message']}")
print(result["status"])  # e.g. "Skilled Worker"
```

200 OK:

```json
{
  "outcome": "ACCEPTED",
  "title": "Immigration status",
  "name": "JANE EXAMPLE DOE",
  "date_of_birth": "1990-01-01",
  "nationality": "CAN",
  "status": "Skilled Worker",
  "valid_from": "2024-01-01",
  "valid_until": "2027-01-01",
  "activities": [
    "live in the UK until 1 January 2027",
    "study, subject to Academic Technology Approved Scheme (ATAS) conditions",
    "travel in and out of the country"
  ],
  "restrictions": ["They cannot access public funds."],
  "reference": "SC-EXAMPLE-12",
  "company_name": "Example Bank, Leeds branch",
  "job_title": "Account opening officer",
  "purpose": "Personal finance (including bank and building society accounts, loans, credit cards and mortgages)",
  "check_date": "2026-10-02",
  "share_code": "AB1CD2EF3",
  "photo_data_url": "data:image/jpeg;base64,/9j/4AAQ…",
  "pdf_data_url": "data:application/pdf;base64,JVBERi0…",
  "checked_at": "2026-10-02T10:14:03.000Z"
}
```

### Asynchronous

- `Authorization` (header, string, required): Bearer followed by your key. `rtw_test_…` keys return sandbox data. `rtw_live_…` keys run a real check. Example: `Bearer rtw_live_…`
- `Idempotency-Key` (header, string): Any string up to 255 characters, unique per check you mean to run. Sending the same key again returns the first check with `200`, so a retry after a network error never runs or charges a second check. Example: `applicant-4411-check-1`
- `share_code` (string, required): The 9-character code the person made at gov.uk/view-prove-immigration-status. These codes start with S; a right to work or right to rent code won’t open this check. Spaces and lower case are fine: we remove spaces and upper-case it. Example: `AB1CD2EF3`
- `date_of_birth` (string, required): The applicant's date of birth as YYYY-MM-DD. It must match the share code, and they must be at least 16. Example: `1990-01-01`
- `company_name` (string, required): Your organisation's name, 1 to 200 characters. gov.uk asks you to include your local office or branch name, and records it as the organisation making the check. Example: `Example Bank, Leeds branch`
- `job_title` (string, required): The job title of the person making the check, 1 to 200 characters. gov.uk records it on the check. Example: `Account opening officer`
- `purpose` (string, required): Why you are checking, as gov.uk asks: one of `driving_licence`, `student_loan`, `education_or_training`, `health_insurance_card`, `personal_finance`, `homelessness_or_council_housing`, `travel`, `other`. gov.uk records its own words for it, which come back in `purpose`. Example: `personal_finance`
- `other_purpose` (string): Your reason, 1 to 200 characters. Required when `purpose` is `other`, and refused otherwise. Example: `Eligibility for a hardship grant`
- `callback_url` (string): Where we post the result when the check ends. Without it we use your default URL for the mode, set on [Webhooks](https://checksharecode.co.uk/app/webhooks), and without that you poll. See [Webhooks](https://checksharecode.co.uk/docs/webhooks.md). Example: `https://api.acme.example/hooks/rtw?applicant=4411`
- `client_reference` (string): Your own id for the check, up to 200 characters, given back in every response and webhook. Use an opaque id, never the applicant’s name, share code or date of birth. Example: `applicant-4411`

The `202` has a `Location` header with the check’s URL, `/api/check/immigration-status/async/chk_…`. `GET` it with the same key, or set a callback URL and we post the result when the check ends. See [Asynchronous checks](https://checksharecode.co.uk/docs/api/check-async.md) and [Webhooks](https://checksharecode.co.uk/docs/webhooks.md).

Request:

```bash
curl https://checksharecode.co.uk/api/check/immigration-status/async \
  -H "Authorization: Bearer $CHECKSHARECODE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: applicant-4411-check-1" \
  -d '{
    "share_code": "AB1CD2EF3",
    "date_of_birth": "1990-01-01",
    "company_name": "Example Bank, Leeds branch",
    "job_title": "Account opening officer",
    "purpose": "personal_finance",
    "callback_url": "https://api.acme.example/hooks/rtw?applicant=4411",
    "client_reference": "applicant-4411"
  }'
```

202 Accepted:

```json
{
  "id": "chk_5f2a8c1e9b7d4a6f8e3c2b1a0d9f8e7c",
  "status": "queued",
  "mode": "live",
  "client_reference": "applicant-4411",
  "callback_url": "https://api.acme.example/hooks/rtw?applicant=4411",
  "attempts": 0,
  "result": null,
  "error": null,
  "result_expires_at": null,
  "result_expired": false,
  "created_at": "2026-09-28T10:00:00.000Z",
  "completed_at": null
}
```

## Try it

Signed in, the web version of this page sends this request with your sandbox key and shows the answer.

## The same for every check

These are written once, for this endpoint, [right to work](https://checksharecode.co.uk/docs/api/right-to-work.md) and [right to rent](https://checksharecode.co.uk/docs/api/right-to-rent.md) alike.

- [Response fields](https://checksharecode.co.uk/docs/api/check.md#response-fields): What each check returns
- [Errors](https://checksharecode.co.uk/docs/api/check.md#errors): Every code, and what to do
- [Rate limits and quota](https://checksharecode.co.uk/docs/api/check.md#limits): One allowance for every check
- [Webhooks](https://checksharecode.co.uk/docs/webhooks.md): For asynchronous checks

See also: [POST /api/check/right-to-rent](https://checksharecode.co.uk/docs/api/right-to-rent.md) · [Responses, errors and limits](https://checksharecode.co.uk/docs/api/check.md)
