API reference
Check a share code
POST https://checksharecode.co.uk/api/check runs the employer check on gov.uk's View a job applicant's right to work details service and returns the result as JSON. A live check takes a few seconds. Nothing is stored: the photo and PDF are only in this response.
Headers
Authorizationstringrequired
Bearer followed by your key.
rtw_test_… keys return sandbox data. rtw_live_… keys run a real check.Example:
Bearer rtw_live_…Body
share_codestringrequired
The 9-character code the applicant got from gov.uk, letters and numbers. Spaces and lower case are fine: we remove spaces and upper-case it.
Example:
AB1CD2EF3date_of_birthstringrequired
The applicant's date of birth as YYYY-MM-DD. They must be at least 16.
Example:
1990-01-01company_namestringrequired
Your organisation's name, 1 to 200 characters. gov.uk records it against the check.
Example:
Acme Ltdcurl https://checksharecode.co.uk/api/check \
-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"
}'200 OK
{
"outcome": "ACCEPTED",
"title": "Right to work",
"name": "JANE EXAMPLE DOE",
"date_of_birth": "1990-01-01",
"nationality": "British",
"permission_type": "Indefinite leave to remain",
"start_date": null,
"expiry_date": null,
"conditions": [],
"restrictions": [],
"reference": "WE-EXAMPLE-12",
"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"
}Response fields
| Field | Type | Meaning |
|---|---|---|
| outcome | "ACCEPTED" | "REJECTED" | Whether gov.uk says this person has the right to work. |
| title | "Right to work" | "Right to rent" | Which kind of share code it was. |
| name | string | Applicant name as gov.uk holds it. |
| permission_type | string | null | For example Skilled Worker visa, or Indefinite leave to remain. |
| start_date, expiry_date | date | null | YYYY-MM-DD. null when gov.uk shows none. Diary a follow-up check before the expiry date. |
| conditions, restrictions | string[] | Work conditions and restrictions, one sentence each. Empty array when there are none. |
| photo_data_url | string | null | Applicant photo as a JPEG data URL. Compare it with the person. |
| pdf_data_url | string | null | The gov.uk PDF as a data URL. Keep it as your record. |
| reference | string | null | gov.uk reference for your audit trail. |
| checked_at | date-time | When the check finished, ISO 8601 UTC. |
Live responses also carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset for your monthly checks, and every response has an X-Request-Id.
Errors
Errors come back as { "error": { "code", "message" } }. Switch on code. message is written for a person and says what to do next. QUOTA_EXCEEDED and PAYMENT_REQUIRED also carry an upgrade_url.
| code | HTTP | What to do |
|---|---|---|
| INVALID_INPUT | 400 | Fix the field named in message. Don't retry as is. |
| UNAUTHENTICATED / INVALID_KEY | 401 | Check the Authorization header and key. |
| QUOTA_EXCEEDED / PAYMENT_REQUIRED | 402 | Plan limit reached. Send the user to upgrade_url. |
| NOT_FOUND | 404 | gov.uk doesn't recognise the share code. Ask the applicant to check it. |
| DOB_MISMATCH | 404 | Code found, date of birth doesn't match. Ask the applicant to check it. |
| RATE_LIMITED | 429 | Too many requests. Back off and retry. |
| GOVUK_UNEXPECTED | 502 | gov.uk returned a page we didn't expect. Retry later. |
| BUSY | 503 | All check slots in use. Retry after the Retry-After seconds. |
| TIMEOUT | 504 | gov.uk was too slow. Safe to retry. |
| INTERNAL | 500 | Our fault. Retry, then contact us with X-Request-Id. |
Rate limits and quota
| Plan | Live checks a month | After that | Requests/second per key |
|---|---|---|---|
| Free | 10 | Refused until the 1st | 5 |
| Pro | 100 | £0.25 per check | 20 |
| Scale | 500 | £0.10 per check | 50 |
Sandbox calls and errors never count. The OpenAPI 3.1 contract is at /openapi.json.