Wie krijgt toegang
De API is exclusief voor Recruiter-tier abonnees:
- Recruiter Stad (€ 149/mnd) — onbeperkt vacatures binnen 1 stad
- Recruiter Regio (€ 299/mnd) — onbeperkt binnen 1 metropoolregio
- Recruiter Landelijk (€ 599/mnd) — onbeperkt binnen heel Nederland (28 sites)
API-toegang is inbegrepen in elke Recruiter-tier. Bekijk tarieven →
API key genereren
Log in op /mijn/api/ en klik op "Genereer API key". Je krijgt een key in dit formaat:
qmg_live_a1b2c3d4e5f6...
Belangrijk: de key is maar één keer zichtbaar. Bewaar 'm in je secret-manager (1Password, AWS Secrets, env-var). Verloren? Klik "Regenereer" — de oude wordt direct ongeldig.
Bij abonnement-opzegging wordt de key automatisch ingetrokken (zie §08).
Authenticatie
Stuur de API key in elke request via één van:
Authorization: Bearer qmg_live_a1b2c3...# ofX-API-Key: qmg_live_a1b2c3...
Beide werken. Wij loggen alleen de laatste 4 tekens van de key voor audit (AVG-conform).
Endpoints
Alle endpoints onder https://questmediagroup.eu/api/v1/.
| Method | Path | Doel |
|---|---|---|
GET | /vacancies | Lijst eigen vacatures |
POST | /vacancies | Eén vacature aanmaken |
PUT | /vacancies/{id} | Eigen vacature updaten |
DELETE | /vacancies/{id} | Eigen vacature soft-delete (is_published=false) |
POST | /vacancies/bulk | Bulk CSV upload (max 500/req) |
GET | /keys/info | Key metadata (masked + usage) |
POST | /keys/regenerate | Nieuwe key (oude vervalt direct) — Supabase Auth, geen API-key |
POST /vacancies — vacature aanmaken
JSON body. Verplicht: title, category, city. Overige optioneel.
curl -X POST https://questmediagroup.eu/api/v1/vacancies \
-H "Authorization: Bearer qmg_live_..." \
-H "Content-Type: application/json" \
-d '{
"title": "Allround Lasser",
"category": "Techniek",
"city": "Rotterdam",
"wijk": "botlek-europoort-maasvlakte",
"employment_type": "Fulltime",
"salary_min": 3200,
"salary_max": 4500,
"apply_whatsapp": "+31612345678",
"apply_email": "jobs@flexwerk-rotterdam.nl",
"expires_at": "2026-06-30",
"description": "Eigen tekst — wordt direct getoond op /vacatures/{slug}/"
}'Response:
{
"ok": true,
"vacancy": {
"id": "9c7e2a14-...",
"slug": "allround-lasser-flexwerk-rotterdam-9c7e",
"url": "https://allesover010.nl/vacatures/allround-lasser-.../"
}
}POST /vacancies/bulk — CSV bulk-upload
Max 500 rijen per upload, max 5 MB. Voor grotere datasets: meerdere uploads.
CSV header (eerste rij verplicht):
title,category,city,wijk,employment_type,salary_min,salary_max,description,apply_whatsapp,apply_email,expires_at
Voorbeeld:
title,category,city,wijk,employment_type,salary_min,salary_max Allround Lasser,Techniek,Rotterdam,botlek-europoort-maasvlakte,Fulltime,3200,4500 Magazijnmedewerker,Logistiek,Rotterdam,waalhaven-eemhaven,Parttime,2400,2800 Servicedesk medewerker,IT,Rotterdam,centrum,Fulltime,3000,3800
Upload:
curl -X POST https://questmediagroup.eu/api/v1/vacancies/bulk \ -H "Authorization: Bearer qmg_live_..." \ -F "file=@vacatures-week-17.csv"
Response:
{
"ok": true,
"inserted": 487,
"errors": [
{ "row": 32, "message": "missing_title" },
{ "row": 89, "message": "invalid_expires_at_format" }
]
}Match webhooks (inkomend)
Wanneer een werkzoekende matcht of solliciteert op één van jouw vacatures, sturen wij een webhook naar de URL die je hebt geconfigureerd in /mijn/api/ (veld api_webhook_url).
Payload (JSON, POST):
POST https://jouw-ats.nl/qmg-webhook
Content-Type: application/json
X-QMG-Signature: sha256=abc123...
{
"event": "match",
"vacancy_id": "9c7e2a14-...",
"vacancy_title": "Allround Lasser",
"match_score": 94,
"alert_type": "match",
"candidate": {
"id": 4721,
"privacy": "full",
"name": "Jan de Vries",
"email": "jan@example.nl",
"phone": "+31612345678",
"skills": ["lassen", "VCA", "MIG/MAG"],
"experience_years": 5
},
"qa_summary": "5 jaar ervaring | VCA: Ja | Beschikbaar per direct"
}Bij privacy: "anonymous" ontbreken naam, email, telefoon. Je krijgt enkel candidate.id + match-score + skills.
Verifieer altijd de signature (zie §09).
Webhook signature verifiëren
Wij signen elk payload met HMAC-SHA256 op basis van het secret dat je in de dashboard configureert (veld api_webhook_secret). Header:
X-QMG-Signature: sha256=<64-hex>
Pseudocode:
expected = "sha256=" + hmac_sha256(raw_body, your_webhook_secret).hexdigest()
if not constant_time_equals(expected, request.headers["X-QMG-Signature"]):
return 401Identiek patroon als Stripe / GitHub. Als je het secret leeg laat: webhook fired ongetekend (afgeraden).
Errors & rate limits
HTTP status codes:
| Code | Betekenis |
|---|---|
| 200 / 201 | Succes |
| 400 | Validation error (zie response body) |
| 401 | missing_api_key of invalid_api_key |
| 403 | Vacature behoort niet aan jou |
| 404 | Vacature niet gevonden |
| 413 | CSV groter dan 500 rijen of 5 MB |
| 429 | Rate limit (komt — tier-gebaseerd) |
| 5xx | Server error — retry met exp. backoff |
Iedere foutmelding heeft een error field met een stabiele code en een leesbare hint.
Rate limit (gepland): Recruiter Stad 1k/dag, Regio 5k/dag, Landelijk 25k/dag. Per maand: GET /keys/info toont je teller.
Wijken — gebruik CBS-slugs
Het veld wijk accepteert deze slugs (CBS / allecijfers.nl indeling):
14 woon-wijken: centrum · noord · delfshaven · kralingen-crooswijk · feijenoord · charlois · prins-alexander · hillegersberg-schiebroek · ijsselmonde · hoogvliet · overschie · hoek-van-holland · pernis · rozenburg
7 industrie/haven-wijken: spaanse-polder · nieuw-mathenesse · waalhaven-eemhaven · vondelingenplaat · botlek-europoort-maasvlakte · rotterdam-noord-west · rivium
MRDH-steden: schiedam · vlaardingen · capelle-aan-den-ijssel · ridderkerk · barendrecht · lansingerland · maassluis · nissewaard · krimpen-aan-den-ijssel · albrandswaard
Andere steden in uitrol: denhaag, amsterdam, utrecht, eindhoven, groningen, alphen. Bij Recruiter Landelijk wordt over alle steden geserveerd.
Onbekende wijk? Wij detecteren automatisch op basis van adres / titel als je veld leeg laat.
Abonnement-degradation
Bij opzegging van je Recruiter-abonnement:
- API-key wordt direct ingetrokken (volgende request → 401)
- Vacature-pagina's blijven indexed (SEO behoud), maar zonder photo, logo, WhatsApp-knop
- Branch-pagina's krijgen "Was partner van 010 — heractiveer" CTA
- Match-webhooks stoppen
- Bestaande job_listings blijven in DB tot je ze hard delete
Heractiveer? Doe een nieuw checkout via /tarieven/. Je krijgt direct een nieuwe API-key + alle vacatures gaan terug naar full-feature mode.
ATS-integratie patronen
De API is door bekende ATS-systemen als volgt te koppelen:
| ATS | Integratie |
|---|---|
| Bullhorn | Custom API trigger op JobOrder.create / .update / .delete → REST call naar QMG |
| Carerix | Vacature-publicatie webhook → bulk CSV elke dag → POST /vacancies/bulk |
| Recruitee | Webhook on JobCreated → POST /vacancies; webhook on Hired → DELETE |
| Otys | OData-export → CSV transform → bulk-upload via cron |
| Eigen software | Direct REST-koppeling met dit document als reference |
Geen integratie-engineer? Lever ons een wekelijkse CSV-export per email — wij draaien 'm voor je via /mijn/api/.
Support
API-issues: api@questmediagroup.eu — reactie binnen 1 werkdag.
Status updates: /status/.
Voor enterprise / volume-deals (> 5000 vacatures): enterprise@questmediagroup.eu.
Quest Media Group · KvK 82781486 · BTW NL862602282B01 · Zwanebloem 47, 2408 LT Alphen aan den Rijn