The Recooty API lets your own website, HR system, or automation tool talk to Recooty directly — no manual copy-paste, no CSV imports.
With it you can:
Show your live jobs anywhere — on your own website, intranet, or a partner's job board.
Create and update jobs from another system — an ATS, an ERP, a spreadsheet-driven workflow, or an automation tool like Power Automate, Zapier, or Make.
Receive applications from your own custom form and have them land in Recooty exactly as if the candidate applied on your careers page.
Pull candidate details — including screening answers and Recooty's AI resume insights — into your own dashboards.
Keep locations and departments in sync so jobs created by machine are filed in the right place.
Everything lives on one page in Recooty: Settings → Integrations → API.
Who this article is for. The first half ("Before you start", "Your two credentials", "Usage, credits and limits") is written for anyone. The per-API sections include the exact requests a developer needs. If you're handing this to a developer, they can start at Jobs API.
In this article:
BEFORE YOU START
1. Your plan must include API Access
The API is a paid feature. If API Access isn't on your plan, you'll see an upgrade prompt when you try to create a token, and every token-based API call returns:
{ "message": "Feature not available to your plan" }with HTTP status 402 Payment Required.
One important exception: the three job listing endpoints (the ones that use your API key) are not plan-gated. They keep working on any plan, because they're what powers careers page feeds and the jobs widget. Everything else — creating jobs, receiving applications, reading candidates, locations, departments — requires API Access.
2. You need the right permission
What you want to do | Permission needed |
See the API page and your API key | API and documentation |
Create or revoke access tokens | Tokens |
If you don't have the Tokens permission, the page still shows your API key and the full documentation, but instead of the token list you'll see:
You do not have permission to create or revoke API tokens. Ask a workspace admin to either grant you the permission or create the token for you.
3. Find your credentials
Go to Settings → Integrations → API. The first card, API Key & Access Tokens, holds both credentials.
YOUR TWO CREDENTIALS
Recooty uses two different credentials, and picking the wrong one is the single most common integration mistake. Every endpoint in the app is tagged so you can tell at a glance.
| API key | Access token |
Tag in the app | REQUIRES API KEY | REQUIRES TOKEN |
What it is | One permanent key per workspace | A personal access token you create yourself |
Where it goes | Already built into the URL |
|
Can read | Published (open) jobs only | Everything your plan allows |
Can write | Nothing | Jobs, applications, locations |
Expires | No | 1 year after it's created |
Safe in front-end code? | Yes — it only exposes jobs you've already published | No — never |
The API key
Your API key is shown at the top of the API page. You don't need to paste it anywhere: Recooty has already embedded it into every URL and code sample on the page tagged REQUIRES API KEY. Copy the request as shown and it works.
The API key only ever returns jobs you have already published publicly, so it is safe to use in browser JavaScript or a public widget.
Access tokens
Everything that writes data or reads candidate information needs a personal access token.
To create one:
Go to Settings → Integrations → API.
Click Create Token (top-right of the API Key & Access Tokens card).
Give it a name that says where it will be used — Website careers form, Power Automate sync, Staging.
Click Create.
Copy the token immediately. It is shown once and never again.
If you lose a token, you can't recover it — revoke it and create a new one.
To revoke one: click Revoke next to the token. It stops working immediately, and any integration using it starts failing with 401.
Good practice:
One token per integration. If one leaks, you revoke just that one.
Tokens expire one year after creation — the expiry date is shown on the token card. Diary a renewal a few weeks before.
Never put a token in front-end JavaScript, a mobile app, or a public repository. Anyone holding it can read every candidate in your workspace.
Tokens are tied to the workspace (team) they were created in. A token can never see another workspace's data.
THE BASICS EVERY REQUEST FOLLOWS
Base URL
<API_BASE_URL>/api/v1/
The exact base URL for your account is shown on the API page — copy it from there.
Headers
Accept: application/json Authorization: Bearer <ACCESS_TOKEN> ← only for REQUIRES TOKEN endpoints Content-Type: application/json ← when you send a JSON body
Responses are always JSON, with the data wrapped under a named key (job, jobs, location, applications, …).
Errors are always JSON with a message, plus an errors object when a field failed validation:
{ "message": "The title field is required.", "errors": { "title": ["The title field is required."] } }Two kinds of ID appear throughout:
| Job ID | Application ID |
Looks like |
|
|
Where it comes from |
|
|
Location and department IDs are ordinary numbers (12, 3).
Rate limits: Recooty does not currently apply a published per-minute limit to these endpoints. Build your integration to pause and retry if it ever receives a 429, and avoid tight polling loops — see Integration recipes.
USAGE, CREDITS AND LIMITS
This is the part most integrations get surprised by, so it's worth reading even if you're not technical.
Three things on your plan can be used up. When any of them runs out, the API replies 402 with a plain-English message — it does not silently do half the work.
Resource | What consumes it | What frees it |
Jobs | Each job that is Open or Internal | Closing a job |
Locations | Each location that exists | Deleting a location |
Application view credits | The first time an application's full details are viewed | Nothing — credits refresh with your plan |
How job credits actually work
A job saved as DRAFT costs nothing.
The moment it becomes Open or Internal, it uses one job credit.
Closing a job gives the credit back.
If you're at your limit and try to publish, you get 402 and the job is not created at all — the whole operation is rolled back, so you won't find a stray draft afterwards.
How location credits work
Every location row counts, whether or not a job uses it.
Creating one over the limit returns 402 and creates nothing.
There is no "find or create" — every
POST /locationsmakes a brand-new row. If your automation calls it on every sync, you will build up duplicates and eventually hit 402. Store the location ID you get back and reuse it.
How application view credits work
This one is genuinely useful to understand:
Call | Costs a credit? | Returns contact details? |
| No | No — names and status only |
| Yes, first time only | Yes — email, phone, resume, AI insights |
Same detail call again, later | No | Yes |
Applications you submitted through the API | No, ever | Yes |
So you can poll the list endpoint as often as you like for free, and only spend a credit when you actually open a candidate.
The last row is worth repeating: an application your own form submitted through POST /jobs/{job_id}/applications is already marked as viewed, at no charge. You already had the candidate's details when you sent them, so Recooty doesn't charge you to read them back.
When credits run out:
{ "message": "You have reached your application view credit limit. Please upgrade your plan to continue." }Important: running out of view credits does not stop applications arriving. Candidates can still apply, the applications are still stored, and the list endpoint still works. You just can't open new ones until you upgrade or your credits refresh.
JOBS API
Everything to do with job postings: reading the jobs you've published, looking one up, and creating or updating jobs from another system.
When you'd use it
Put your jobs on your own website — your web team renders the live list from the feed, styled however they like.
Feed a partner site or internal portal with your open roles.
Keep Recooty in sync with your ATS or HR system — when a requisition opens over there, the job appears in Recooty automatically; when it's filled, the job closes.
Avoid duplicates by checking whether a job code already exists before creating it.
The endpoints
What it does | Request | Credential | Status |
List published jobs |
| API key | Stable |
Retrieve one job |
| API key | Stable |
Find a job by job code |
| API key | Stable |
Create a job |
| Access token | Beta |
Update a job |
| Access token | Beta |
About the Beta tag. Create and update work today and are used in production integrations, but the response shape may still gain fields. Nothing will be removed without notice. Build against them, and let us know what you're using them for.
How to use it
List your published jobs — no token needed, key already in the URL:
curl --request GET \ --url <API_BASE_URL>/api/v1/jobs/<API_KEY> \ --header 'Accept: application/json'
{ "company": "TechFlow Solutions", "job_count": 3, "jobs": [ { "id": "7f8a9b2c3d4e5f6a7b8c9d0e1f2a3b4c", "title": "Senior Frontend Developer", "jobcode": "TF001", "description": "<strong>Job Responsibilities</strong>…", "city": "San Francisco", "state": "California", "country": "United States", "zip": "94105", "date": "2024-01-15 09:30:45", "industry": "Technology", "employment_type": "Full Time", "remote": "Hybrid", "experience": "Mid Level", "details_url_external": "https://careers.example.com/techflow/senior-frontend", "apply_url_external": "https://careers.example.com/techflow/senior-frontend/apply" } ] }details_url_externalandapply_url_externalare ready-made links to your Recooty careers page — the simplest way to build a job list on your own site is to render the titles and point them at these URLs.Check whether a job already exists, before creating it:
curl --request GET \ --url '<API_BASE_URL>/api/v1/jobs/<API_KEY>?code=REQ-10432' \ --header 'Accept: application/json'
job_count: 0means it doesn't exist yet → create it.job_count: 1means it does → takejobs[0].idand update it instead.Create a job:
curl --request POST \ --url <API_BASE_URL>/api/v1/jobs \ --header 'Accept: application/json' \ --header 'Authorization: Bearer <ACCESS_TOKEN>' \ --header 'Content-Type: application/json' \ --data '{ "title": "Software Engineer", "code": "ENG-001", "description": "<p>We are hiring a software engineer…</p>", "location_id": 1, "department_id": 1, "location_type": "REMOTE", "experience_required": "MID_SENIOR", "employment_type": "FULL_TIME", "resume_required": true, "status": "CAREER_PAGE" }'Returns 201 with the new job, including the
idyou'll use for every future update.Fields on create:
Field | Required | Notes |
| Yes | Max 512 characters |
| Yes | Max 24 characters, letters/numbers/hyphens/underscores only, unique within your workspace |
| Yes | Minimum 30 words. HTML allowed and cleaned server-side |
| Yes | Must be one of your locations — get it from the Locations API |
| Yes |
|
| Yes |
|
| Yes |
|
| Yes |
|
| Yes |
|
| No | Must be one of your departments |
| No | Free text |
| No | If you send one you must send both, and |
| With pay |
|
| With pay | ISO code — USD, GBP, EUR, INR, … |
| No | Screening questions — see below |
Publishing is controlled by status:
You send | What happens |
| Saved privately in Recooty. Uses no job credit. Nobody can see it |
| Goes live on your Recooty careers page. Uses one job credit |
| Goes live and is submitted to job boards for approval. Uses one job credit |
Update a job — send only the fields you're changing:
curl --request PATCH \ --url <API_BASE_URL>/api/v1/jobs/<JOB_ID> \ --header 'Accept: application/json' \ --header 'Authorization: Bearer <ACCESS_TOKEN>' \ --header 'Content-Type: application/json' \ --data '{ "status": "CLOSED" }'Status changes follow strict rules. Anything not in this table returns 409:
Current status | Can change to |
Draft | CAREER_PAGE, JOB_BOARDS |
Open | CLOSED, INTERNAL |
Internal | CLOSED |
Closed | (nothing — closed is final via the API) |
Notes / what to keep in mind
Job code is your anchor. It's unique per workspace and searchable, so use your own system's reference number as the code. That single field is what lets an automation decide "update the existing job" instead of creating a duplicate every run. You don't need any custom fields to track the link.
The single-job lookup only returns open jobs.
GET /jobs/<API_KEY>/<JOB_ID>returns 404 for a draft, internal, or closed job. If you need a job in any status, use the job-code lookup instead — that one searches everything.The plain list only shows open jobs too. Drafts, internal and closed jobs never appear in the public feed. That's deliberate: it's a public endpoint.
Job codes look different in different responses. The API-key lookups return it as
jobcode; create and update return it ascode. Same value, legacy naming.Descriptions must be at least 30 words. Short placeholder text will be rejected with 422. This protects your job board distribution — most boards reject thin descriptions.
Editing an approved job's title or description queues a re-approval. If the job is already approved on job boards, your edit is parked rather than applied. The response includes
"pending_reapproval": true, and the live posting keeps the old text until an admin approves. Your API call still succeeds.Screening questions can only be set when the job is created. Sending
fieldsorresume_requiredon an update is rejected with 422 and the message "Screening questions cannot be updated through this endpoint." Change them in the Recooty UI.Jobs are never deleted, only closed. There is no delete endpoint by design — closing preserves the applications attached to the job.
Closed jobs can't be reopened via the API in this version. Reopen it in the Recooty UI, or create a new job.
There are no job webhooks yet. To detect changes, use the job-code lookup on a schedule rather than polling constantly.
Screening questions (fields, optional on create):
"fields": [ { "field_name": "Years of React experience", "field_type": "NUMBER", "is_required": true }, { "field_name": "Preferred location", "field_type": "DROP_DOWN", "is_required": true, "data": ["London", "Remote"] }, { "field_name": "Do you need visa sponsorship?", "field_type": "TOGGLE", "is_required": true, "auto_reject": true } ]field_type accepts TEXT, TEXT_AREA, DROP_DOWN, CHECK_BOX, RADIO, NUMBER, DATE, FILE, URL, TOGGLE, BOOLEAN, INFORMATION. data (the list of options) is required for DROP_DOWN, CHECK_BOX and RADIO. auto_reject only works on TOGGLE fields, whose options are fixed to Yes/No.
Troubleshooting
Symptom | Most likely cause | Fix |
Job list is empty but you have jobs | None are Open — they're drafts, internal, or closed | Publish one, or use the |
A job you can see in Recooty returns 404 from the single-job lookup | That endpoint only serves open jobs | Use |
422 on | A job with that code already exists in your workspace | Look it up by code and update it instead of creating |
422 on | Fewer than 30 words | Expand the description |
422 on | The location belongs to a different workspace, or was deleted | Call |
422 on | You sent | Send all four, or none |
409 on a status change | Not an allowed transition | Check the transition table above |
402 when publishing | You're at your active-job limit | Close a job you don't need, or upgrade |
Job created but title change didn't appear | It's queued for job-board re-approval | Check |
CANDIDATES API
What it is
The candidate side: sending applications into Recooty from your own form, listing who applied, and opening a candidate's full profile including Recooty's AI resume insights.
When you'd use it
You built your own application form — on your website, in a chatbot, inside your intranet — and want the submissions to land in Recooty's pipeline exactly like careers-page applications.
You want applicant counts on an internal dashboard without giving people Recooty logins.
You're piping candidate data into a BI tool, a background-check vendor, or your HRIS.
The endpoints
What it does | Request | Credential |
Submit an application |
| Access token |
List a job's applications |
| Access token |
View one application in full |
| Access token |
Note on the submit URL. Older integrations use the singular /application. It still works, but it's deprecated and its responses now carry a Deprecation: true header. Move to the plural /applications when you next touch the code.
How to use it
Submit an application. The body must be multipart/form-data because it carries a CV file:
curl --request POST \ --url <API_BASE_URL>/api/v1/jobs/<JOB_ID>/applications \ --header 'Accept: application/json' \ --header 'Authorization: Bearer <ACCESS_TOKEN>' \ --header 'Content-Type: multipart/form-data' \ --form 'first_name=John' \ --form 'last_name=Doe' \ --form '[email protected]' \ --form 'mobile_number=9999999999' \ --form 'resume=@/path/to/resume.pdf'
Field | Required | Rules |
| Yes | 2–512 characters |
| Yes | 2–512 characters |
| Yes | Valid email address |
| Yes | Also accepted as |
| Yes | PDF, DOC or DOCX only |
The response returns the new application_id — store it if you want to fetch the candidate later.
List a job's applications (free, no contact details):
curl --request GET \ --url <API_BASE_URL>/api/v1/jobs/<JOB_ID>/applications \ --header 'Accept: application/json' \ --header 'Authorization: Bearer <ACCESS_TOKEN>'
Returns 10 per page, newest first. Follow
next_page_url, or add?page=2.Open one candidate (costs one view credit the first time):
curl --request GET \ --url <API_BASE_URL>/api/v1/applications/<APPLICATION_ID> \ --header 'Accept: application/json' \ --header 'Authorization: Bearer <ACCESS_TOKEN>'
This returns everything: contact details, resume link, answers to your screening questions, current pipeline stage, and an
ai_insightsblock:"ai_insights": { "parse_status": "PARSED", "score": 78, "pros": ["Relevant experience in a similar role."], "cons": ["No exposure to one of the required reporting tools."], "resume": { "personal_info": {}, "experience": [], "education": [], "skills": [] } }parse_statustells you what state the AI analysis is in:
Value | Meaning | Should you poll again? |
| Not started | Yes, shortly |
| Being analysed right now | Yes — this will change on its own |
| Done — score, pros, cons, resume are populated | No |
| Couldn't be analysed (unreadable or image-only CV) | No — it won't change |
| Analysis was stopped | No |
resume is null — not an empty skeleton — until parsing finishes, so "no data yet" is never confused with "a CV with nothing in it".
Notes / what to keep in mind
Submitting an application doesn't spend a view credit, and never will for that application. Recooty marks it as already seen, since you supplied the data.
The list endpoint is free and contains no personal contact details — just names, dates and stage. Poll it as much as you like; spend a credit only when you open someone.
Once you've opened a candidate, opening them again is free. Credits are charged per candidate, not per request.
One application per email address per job. A second submission with the same email returns 409. This is a deliberate anti-duplicate guard, not an error in your code — treat 409 as "already applied" and move on.
You can only apply to jobs that are open or internal. A closed or draft job returns 410.
CV file types are strictly PDF, DOC and DOCX. Images, ZIPs and plain text are rejected with 422.
AI insights are machine-generated. The score, pros and cons come from Recooty's model, not a human recruiter. If you display them, label them as AI output so your hiring managers don't mistake them for a colleague's assessment.
AI insights arrive after the application does. Right after submission the status will usually be PROCESSING. Don't build a flow that assumes the score is there immediately.
A token can only reach its own workspace's jobs. Requesting a job from another workspace returns 401.
Troubleshooting
Symptom | Most likely cause | Fix |
409 Duplicate Application already in the system | That email already applied to this job | Expected behaviour — show the candidate a friendly "you've already applied" message |
410 The job is expired or no longer available | The job is closed or still a draft | Check the job's status before showing your form |
422 on | Wrong file type, or the file didn't reach the server | Restrict your upload control to .pdf, .doc, .docx, and confirm you're sending multipart/form-data |
422 on | Field missing entirely | Send |
402 when opening a candidate | View credits exhausted | Upgrade, or wait for credits to refresh. Applications are still arriving safely |
| Analysis still running, or the CV couldn't be read | Check |
401 on every call | Token expired, revoked, or copied incorrectly | Tokens last one year. Create a new one and update your integration |
Applications arrive but with no screening answers | The job's screening questions weren't included in your submission | Screening answers are optional in the API; send them if your own form collects them |
LOCATIONS API
Locations are the addresses your jobs are attached to. Every job needs one. This API lists them, creates new ones, and edits existing ones.
When you'd use it
Almost always as a supporting step for the Jobs API: before you can create a job from another system, you need a location_id.
Look up the ID of a location you already have in Recooty.
Create a new office when you open one, so jobs can be filed against it.
Correct an address that changed.
The endpoints
What it does | Request | Credential | Status |
List your locations |
| Access token | Beta |
Create a location |
| Access token | Beta |
Update a location |
| Access token | Beta |
How to use it
List what you already have (25 per page):
curl --request GET \ --url <API_BASE_URL>/api/v1/locations \ --header 'Accept: application/json' \ --header 'Authorization: Bearer <ACCESS_TOKEN>'
{ "locations": { "data": [ { "id": 1, "name": "Headquarters", "address": "123 Main Street", "city": "San Francisco", "state": "California", "country": "United States", "country_code": "US", "zip_code": "94105", "is_default": true } ] } }Take the
idand use it aslocation_idwhen creating a job.Create one only if it doesn't exist:
curl --request POST \ --url <API_BASE_URL>/api/v1/locations \ --header 'Accept: application/json' \ --header 'Authorization: Bearer <ACCESS_TOKEN>' \ --header 'Content-Type: application/json' \ --data '{ "name": "Headquarters", "address": "123 Main Street", "city": "San Francisco", "state": "California", "country": "United States", "country_code": "US", "zip_code": "94105" }'Every field is individually optional, but you must send at least one of
name,cityoraddress. If you leavenameout, Recooty builds one from city, state (or the address).country_codemust be exactly two letters.zip_codeis also accepted aszip.Update one:
curl --request PATCH \ --url <API_BASE_URL>/api/v1/locations/<LOCATION_ID> \ --header 'Accept: application/json' \ --header 'Authorization: Bearer <ACCESS_TOKEN>' \ --header 'Content-Type: application/json' \ --data '{ "address": "500 Market Street", "zip_code": "94103" }'
Notes / what to keep in mind
This is the number-one place automations go wrong. There is no "find or create". Every
POST /locationscreates a brand-new row, even if an identical address already exists. An automation that creates a location on every sync will fill your account with duplicates and eventually hit your location limit. The fix: callGET /locationsfirst, match on your side, and only create when there's genuinely no match. Store the ID you get back and reuse it forever.Locations are shared. Every job pointing at a location shares the same address record, so editing it changes the address on all of those jobs at once. If only one job's address changed, create a new location for it instead of editing the shared one.
Every location counts towards your plan limit, whether or not a job uses it. Housekeeping matters.
Creating over the limit changes nothing. The operation is wrapped in a transaction, so a 402 leaves no half-created row behind.
There's no delete endpoint. Remove unused locations in the Recooty UI.
Troubleshooting
Symptom | Most likely cause | Fix |
Duplicate offices piling up | Your automation creates a location every run | Look up first, create only on no match, cache the ID |
402 You have reached your location limit | Too many locations, usually from the above | Delete unused locations in the UI, or upgrade |
422 on | Not exactly two characters | Use the ISO code — US, GB, IN |
422 — nothing identifies the location | You sent none of | Send at least one |
404 on update | The location belongs to another workspace, or was deleted | Re-list and use a current ID |
Editing one job's address changed several jobs | They all share that location | Create a separate location for that job |
DEPARTMENTS API
A read-only list of the departments in your workspace, so you can tag jobs to the right team.
When you'd use it
To resolve a department_id before creating or updating a job. Department names in your HR system rarely match Recooty's IDs, so you look them up here and map them once.
The endpoint
What it does | Request | Credential | Status |
List your departments |
| Access token | Beta |
How to use it
curl --request GET \ --url <API_BASE_URL>/api/v1/departments \ --header 'Accept: application/json' \ --header 'Authorization: Bearer <ACCESS_TOKEN>'
{ "departments": { "data": [ { "id": 1, "name": "Engineering" }, { "id": 2, "name": "Marketing" } ] } }Use id as department_id on a job.
Notes / what to keep in mind
Read-only. You cannot create, rename or delete departments through the API — do that in the Recooty UI. This is intentional: departments drive reporting and permissions, so they're managed by people, not machines.
department_idis optional on a job. Leave it out if you don't use departments.Departments don't consume any credit or limit.
Returns 25 per page. With more than 25, follow
next_page_urlor add?page=2— a common cause of "our department is missing" is only reading page one.Sorted alphabetically by name, not by ID.
Troubleshooting
Symptom | Most likely cause | Fix |
A department is missing from the response | It's on a later page | Follow |
422 on | The ID belongs to another workspace, or was deleted | Re-list and use a current ID |
You need a new department | Not possible via the API | Create it in Recooty, then re-list to get its ID |
The list is empty | Your workspace has no departments yet | Create one in Recooty, or omit |
ERROR CODES — THE COMPLETE REFERENCE
Every Recooty API error returns a JSON message. The HTTP status tells you what kind of problem it is and, crucially, whether retrying will help.
Code | Meaning | Typical message | Retry? |
200 / 201 | Success | — | — |
401 | Not authenticated, or the resource belongs to another workspace | Unauthorized | No — fix the token |
402 | Plan or credit problem | Feature not available to your plan / You have reached your active job limit… / You have reached your location limit… / You have reached your application view credit limit… | No — upgrade or free up capacity |
404 | Not found, or not visible to you | Job post not found, Location not found | No |
409 | Conflict with the current state | Duplicate Application already in the system, or an invalid status transition | No — it means "already done" or "not allowed from here" |
410 | The job is gone or closed | The job is expired or no longer available | No |
422 | A field failed validation | Field-by-field detail in errors | No — fix the data |
429 | Too many requests | — | Yes — wait and retry |
500 | Something broke on our side | Unable to save job, Unable to fetch applications, … | Yes — retry with backoff; contact support if it persists |
The three codes people misread
402 is not one problem, it's two. Read the message:
"Feature not available to your plan" → API Access isn't on your plan at all. Nothing will work until you upgrade.
"You have reached your … limit" → your plan is fine, you've simply used up jobs, locations or view credits. Free some up or upgrade.
409 usually means "it already happened". A duplicate application isn't a failure — the candidate is already in your pipeline. Handle it as a normal outcome, not an alert.
401 on an integration that used to work almost always means an expired or revoked token. Tokens last one year. Check the expiry date on the token card in Recooty.
INTEGRATION RECIPES
Sync jobs from another system into Recooty
Run this whenever a requisition changes in your system:
Resolve the location. Reuse a stored
location_idif you have one. Only if you don't, callGET /locations, look for a match, and create one as a last resort. Cache the ID.Resolve the department (if you use them) with
GET /departments. Map names to IDs once and cache.Check whether the job exists:
GET /jobs/<API_KEY>?code=<YOUR_REFERENCE>.job_count: 0→POST /jobswithcodeset to your reference.job_count: 1→ takejobs[0].idandPATCH /jobs/{id}with only the changed fields.
Mirror the status. Requisition filled or cancelled → PATCH with
status: "CLOSED". Reopened → publish withCAREER_PAGE. The lookup response includes the current status, so skip the call when nothing changed.
Because job code is unique per workspace, this loop is safe to run repeatedly — it will never create a duplicate.
Put your live jobs on your own website
Copy the List published jobs URL from the API page (your key is already in it).
Have your web team fetch it and render title, city, employment_type and remote.
Link each entry to
details_url_external, and any Apply button toapply_url_external.
No token needed, so this is safe to run from browser JavaScript. If you'd rather not write code at all, use the Jobs Widget instead — see the widget article.
Accept applications from your own form
Create an access token named after the form.
Store it on your server, never in the page.
On submit, POST to
/jobs/<JOB_ID>/applicationsas multipart/form-data from your backend.Handle 409 as "you've already applied", and 410 as "this role has closed".
Pull applicants into a dashboard
Poll
GET /jobs/<JOB_ID>/applicationson a schedule — free, no contact details.Show counts, names and stages from that alone.
Call
GET /applications/<APPLICATION_ID>only when someone actually clicks into a candidate. That's when the view credit is spent.
FREQUENTLY ASKED QUESTIONS
Do I need a developer?
For reading and displaying jobs, not necessarily — the Jobs Widget covers that with no code. For anything that writes into Recooty or reads candidates, yes.
What happens if my plan doesn't include API Access?
The API page is still visible and your API key still works for the three job-listing endpoints. Everything else returns 402 until you upgrade.
What happens if I run out of application view credits?
Applications keep arriving normally and nothing is lost. You can still list them. Opening a candidate you haven't opened before returns 402 until credits refresh or you upgrade. Candidates you've already opened stay open.
What happens if I hit my job limit?
Publishing another job returns 402 and creates nothing. Close a job you no longer need — that frees the credit immediately — or upgrade. Drafts are free, so you can stage work in advance.
What happens if I hit my location limit?
Creating another location returns 402 and creates nothing. Delete unused locations in the UI. This limit is usually hit by an automation creating duplicates — see the Locations notes.
Can I delete a job?
No, and that's deliberate — deleting would take its applications with it. Close it instead.
Can I reopen a closed job?
Not through the API in this version. Reopen it in the Recooty UI, or create a new job.
Can I get notified when something happens, instead of polling?
Recooty has webhooks for application events (Settings → Integrations → Webhooks). Job events aren't covered yet — for those, use the job-code lookup on a schedule.
My token stopped working.
Tokens expire one year after creation, and revoking one takes effect immediately. Check the expiry on the token card, then create a replacement.
Someone left the company — what should I do with their tokens?
Revoke them. Tokens are created by a person but act on the whole workspace, so treat them like any other shared credential during offboarding.
Is my API key sensitive?
Less so than a token. It only returns jobs you've already published publicly, so it's safe in a website or widget. It is not a password and can't be used to write anything or read candidates.
Can one workspace see another's data?
No. Every token is bound to a single workspace when it's created, and requests for another workspace's jobs or locations return 401 or 404.
Which endpoints are Beta?
Create/update job, all three location endpoints, and list departments. They work in production today; their responses may gain fields, but nothing will be removed without notice. They're marked with a Beta tag on the API page.
GETTING HELP
Start on the API page — Settings → Integrations → API. Every endpoint has a working example with your own key already filled in, plus a sample response.
Read the error message. Recooty's API returns plain-English messages, and the status code tells you whether retrying will help.
Still stuck? Contact Recooty support with: the endpoint you called, the HTTP status, the full JSON error, and roughly when it happened. That's usually enough to resolve it on the first reply.
Please never share an access token in a support ticket, email, or screenshot. Support never needs it.
