Updated June 15, 2026
/api/v1/vacancies/{slug}/canonical-url
curl -X POST \
"https://app.recruitsome.com/api/v1/vacancies/{slug}/canonical-url" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
const response = await fetch('https://app.recruitsome.com/api/v1/vacancies/{slug}/canonical-url', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json',
},
});
const data = await response.json();
console.log(data);
use Illuminate\Support\Facades\Http;
$response = Http::withToken('YOUR_API_KEY')
->acceptJson()
->post('https://app.recruitsome.com/api/v1/vacancies/{slug}/canonical-url');
$data = $response->json();
When your website publishes a vacancy it pulled from Recruitsome, call this endpoint to report back the canonical public URL your site assigned to it. Recruitsome stores that URL and uses it verbatim wherever it links to the vacancy — most importantly, in the vacancy link added to candidate intake/interview invitations.
Use this when your website generates its own URLs (slugs) that don't exactly match Recruitsome's. Reporting the real URL means candidate e-mails always link to the right page — no slug guessing, no broken links. If you don't report a URL, Recruitsome falls back to the Vacancy URL pattern configured under Settings → Integrations → Company website.
Authentication
Requires an API key with the vacancies:write scope (included in the Career website preset).
Warning
This scope is new. Existing scoped keys don't have it — add vacancies:write (or regenerate the key) before calling this endpoint, otherwise you'll get a 403. Legacy full-access keys from before scopes existed keep working without changes. The URL you report must also be on your own career website domain.
Path parameter
| Parameter | Description |
|---|---|
slug | The vacancy's publication_slug, exactly as returned by GET /vacancies and GET /vacancies/{slug}. |
Body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | yes | The full canonical URL on your website. Must be https:// (max 2048 chars). |
Rate limit
This endpoint is throttled at 60 requests per minute per API key. Exceeding it returns a 429 Too Many Requests response — batch your publish callbacks rather than reporting your full vacancy catalog in one burst.
Example
curl -X POST https://app.recruitsome.com/api/v1/vacancies/maintenance-engineer/canonical-url \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://www.yourcompany.com/vacatures/maintenance-engineer-2"
}'const response = await fetch(
'https://app.recruitsome.com/api/v1/vacancies/maintenance-engineer/canonical-url',
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://www.yourcompany.com/vacatures/maintenance-engineer-2'
})
}
);
const result = await response.json();Response 200
{
"message": "Canonical vacancy URL stored",
"data": {
"slug": "maintenance-engineer",
"canonical_url": "https://www.yourcompany.com/vacatures/maintenance-engineer-2"
}
}Error responses
| Status | When | Fix |
|---|---|---|
401 | Missing or invalid API key | Send a valid key as Authorization: Bearer YOUR_API_KEY |
403 | API key lacks the vacancies:write scope | Add the scope to your key or regenerate it |
404 | No website publication exists for this slug — unknown slug, or the vacancy is only published on other channels (e.g. a job board) | Only report URLs for slugs returned by GET /vacancies |
422 | The URL fails validation (see below) | Send an https:// URL on your own career website domain |
429 | More than 60 requests in a minute | Slow down and retry after the minute window resets |
422 — URL on a non-allowlisted host
The reported host must match your configured career website domain (or one of your own Recruitsome domains):
{
"message": "The URL host must match your configured career website domain.",
"errors": {
"url": [
"The URL host must match your configured career website domain."
]
}
}422 — URL is not https://
{
"message": "The url field must start with one of the following: https://.",
"errors": {
"url": [
"The url field must start with one of the following: https://."
]
}
}A reported URL always wins over the configured pattern. To go back to the pattern, simply stop reporting a URL for new publications — existing stored URLs stay until overwritten.