# Right to work

> `POST https://checksharecode.co.uk/api/check/right-to-work` checks a candidate or employee can work in the UK, on gov.uk, as their employer. 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/right-to-work

Synchronous: `POST https://checksharecode.co.uk/api/check/right-to-work`. Asynchronous: `POST https://checksharecode.co.uk/api/check/right-to-work/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 candidate made at gov.uk/prove-right-to-work. A 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 records it as the employer making the check. Example: `Acme Ltd`

Don’t send `checker_type`: it is for right to rent, and a right to work request with it is refused with `400 INVALID_INPUT`. You don’t need `check` either, as the endpoint names the check. If you send it, it must be `right_to_work`.

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/right-to-work \
  -H "authorization: Bearer $CHECKSHARECODE_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "share_code": "AB1CD2EF3",
    "date_of_birth": "1990-01-01",
    "company_name": "Acme Ltd"
  }'
```

Node.js:

```js
const res = await fetch('https://checksharecode.co.uk/api/check/right-to-work', {
  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: 'Acme Ltd',
  }),
});

const result = await res.json();
if (!res.ok) throw new Error(`${result.error.code}: ${result.error.message}`);
console.log(result.outcome); // "ACCEPTED" or "REJECTED"
```

Python:

```python
import os
import requests

res = requests.post(
    "https://checksharecode.co.uk/api/check/right-to-work",
    headers={"authorization": f"Bearer {os.environ['CHECKSHARECODE_API_KEY']}"},
    json={
        "share_code": "AB1CD2EF3",
        "date_of_birth": "1990-01-01",  # YYYY-MM-DD
        "company_name": "Acme Ltd",
    },
    timeout=60,
)
result = res.json()
if not res.ok:
    raise RuntimeError(f"{result['error']['code']}: {result['error']['message']}")
print(result["outcome"])  # "ACCEPTED" or "REJECTED"
```

200 OK:

```json
{
  "outcome": "ACCEPTED",
  "title": "Right to work",
  "name": "JANE EXAMPLE DOE",
  "date_of_birth": "1990-01-01",
  "details": "They have the right to work in the UK.",
  "nationality": null,
  "permission_type": null,
  "start_date": null,
  "expiry_date": null,
  "recheck_date": null,
  "conditions": [],
  "restrictions": [],
  "reference": "WE-EXAMPLE-12",
  "company_name": "Acme Ltd",
  "check_date": "2026-09-27",
  "share_code": "AB1CD2EF3",
  "photo_data_url": "data:image/jpeg;base64,/9j/4AAQ…",
  "pdf_data_url": "data:application/pdf;base64,JVBERi0…",
  "checked_at": "2026-09-27T10: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 candidate made at gov.uk/prove-right-to-work. A 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 records it as the employer making the check. Example: `Acme Ltd`
- `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/right-to-work/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/right-to-work/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": "Acme Ltd",
    "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 both checks

These are written once, for this endpoint 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): One shape, two titles
- [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 both checks
- [Webhooks](https://checksharecode.co.uk/docs/webhooks.md): For asynchronous checks

See also: [Quickstart](https://checksharecode.co.uk/docs/quickstart.md) · [POST /api/check/right-to-rent](https://checksharecode.co.uk/docs/api/right-to-rent.md)
