All guides
Guide
Getting started
From nothing to your first response in three steps. Every call in these guides only reads, so trying them changes nothing. Not writing code? Choose another way to connect.
1. Get a key
If your organisation (an employer, developer, council, charity or training provider) has a verified account with us, sign in and open API access in your dashboard. Create a key there and it can read jobs (jobs:read) and Section 106 progress (s106:read) straight away. New keys start on the Evaluation allowance of 100 calls an hour and 10,000 a month.
Anonymous resident statistics (candidates:read) are requested on the same page with a short description of your purpose, and work once we approve them. The developer compliance export (compliance:read) is the one scope you cannot request yourself: our team sets it up. If your account is not verified yet, the API access page tells you how to verify it; no account at all, use the partnerships form.
A key is shown to you once. We keep only a one-way hash of it, so we cannot show it again: if you lose it, rotate it to get a new one. Store it as a secret, never in client-side code or a public repository.
2. Make a call
List the five newest live opportunities in Southwark:
curl -s "https://opportunityplatform.co.uk/api/v1/jobs?borough=southwark&limit=5" \
-H "Authorization: Bearer $OP_API_KEY"Set OP_API_KEY in your shell first. A missing, unknown or revoked key returns 401 with error.code unauthorized. See Authentication.
3. Read the response
{
"data": [
{
"id": "3f1a9c2e-5b41-4a7e-9c3d-1e2f4a6b8c0d",
"title": "Site Carpenter",
"type": "job",
"location": "Bermondsey, London",
"borough": "Southwark",
"salary": "£38,000 - £44,000",
"closingDate": "2027-03-31T00:00:00.000Z",
"description": "Second-fix carpentry on a residential block.",
"url": "https://opportunityplatform.co.uk/opportunities/site-carpenter-bermondsey"
}
],
"meta": { "returned": 1, "limit": 5, "next_cursor": null }
}Three things worth knowing before you build on this:
salaryis free text, oftenCompetitive. Do not parse it as a number without handling that.boroughis returned as stored, so it may be a display name or a slug. Normalise before you compare.- Send applicants to
url. That is the public listing, and it is where the application is recorded against the place.
More than one page? Pass meta.next_cursor back as cursor; see Pagination.
Every response also carries your remaining allowance in X-RateLimit-* headers. See Rate limits and quotas.
Next
- Browse every endpoint and field in the API reference.
- Get told when something happens instead of polling: Webhooks.
- Generate a client from /api/v1/openapi.json.