Move an existing /v2 integration to v3, one endpoint at a time.
JOIN API v3 replaces v2. Your existing API key already works with v3, so you can move over one endpoint at a time.
- Same data. v2 and v3 read and write the same jobs, applications, candidates and locations.
- Same key. Your v2 key was converted to a company API token automatically. Its value did not change.
- Your pace. Both versions run side by side until v2 is switched off.
Key dates
| Date | Event |
|---|---|
| v3 launch | v3 is live. v2 is deprecated and receives only bug fixes and security patches. |
| 31 October 2027 | v2 stops working. Every request to /v2 fails after this date. |
Steps
- Find your token. Go to Settings → Developer → API tokens. Your v2 key is listed there, named after the admin who owned it, for example "Sarah's API Token". The page is available to System Admins.
- Keep the same key. Send it on every request as
Authorization: Bearer <your key>. If the key is lost, create a new token and revoke the old one. New tokens work with both v2 and v3. - Change the URL. Replace
/v2/with/v3/in each request. - Update your code for the new format. See Differences below. Move one endpoint at a time and test it before moving the next.
- Remove v2 calls before 31 October 2027.
Differences
| Topic | v2 | v3 |
|---|---|---|
| API key | One personal key per user | Company tokens, up to 10, managed by System Admins. New tokens start with join_sk_ |
| Responses | Bare objects and arrays | Always wrapped: { "data": ... } |
| Pagination | Page numbers, X-Total-Count header | limit (max 50) and cursor. Pass nextCursor for the next page; null means the last page |
| Errors | Varies by endpoint | Always { "error": { "code", "message", "details" } }. Branch on code |
| Rate limits | 40 requests per 20 seconds | 600 requests per minute and 100 per 10 seconds, per token. On 429, wait Retry-After seconds |
| Application status | state, hiringState, stage | status (ACTIVE, OFFER, REJECTED, HIRED) and currentPipelineStage |
| Moving an application | Not available | PUT /v3/applications/{id}/pipeline-stage with a stage from GET /v3/jobs/{jobId}/pipeline |
| External ID | PATCH /v2/applications/{id}/externalData | PATCH /v3/applications/{id} with externalId |
| Deleting an application | DELETE /v2/applications/{id} | Not available. Remove the candidate from the job in JOIN |
| Job on an application | Full job object | jobId only |
| Candidate IDs | Global candidate ID | Company candidate ID, the id returned by /v3/candidates |
| Renamed fields | phone, JOIN_CV, lastUpdatedAt | phoneNumber, CV, updatedAt |
| Job category and seniority | Returned | Not returned |
Support
Contact JOIN support with the endpoint, the time of the request, and the code from the error response.