Submitting Candidates

Learn how to create new candidates in the applicant tracking system (ATS) of your education region, including interactions and attachments, using the asynchronous Mutation Engine.

This article focuses on initial submission of candidate data. Finding existing candidates and updating them are covered in subsequent articles.

Start with the /schema endpoint

Before submitting any candidate data, you should always retrieve the schema for your region using the /schema endpoint.

The candidate data model is:

  • Region-specific

  • Partially dynamic

  • Strictly validated at runtime

The /schema endpoint returns the authoritative JSON Schema that the API uses internally to validate candidate payloads. There is no abstraction or translation layer between this schema and the actual validation logic. You should always base payload construction and client-side validation on the response of this endpoint.

If a payload validates against the schema returned by /schema, it will validate against the API.

Schema

The schema endpoint provides the authoritative definition of the candidate request payload for your education region.

Candidate creation endpoints

The API provides multiple ways to submit candidate data, depending on your use case.

Create one or more candidates

Use POST /candidates to create one or more new candidates in a single request.

You can create up to 10 candidates per request.

Key characteristics:

  • Accepts an array of candidate payloads

  • Supports inline creation of:

    • Interactions

    • Attachments

    • Custom fields

  • Processed asynchronously via the Mutation Engine

  • Returns a 202 Accepted response

This endpoint is ideal for:

  • Bulk imports

  • Form submissions batched together

  • Initial data migrations

Upsert a candidate

Use POST /candidates/upsert when you want to create or update a candidate in a single call.

Behavior:

  • If a candidate with the same email or phone already exists, it is updated

  • Otherwise, a new candidate is created

Custom fields are only applied when a candidate is created, not when an existing candidate is updated via upsert.

This endpoint is useful when:

  • You do not know whether a candidate already exists, for example in forms in your website or application.

  • You want idempotent, fire-and-forget behavior

When creating candidates, you may include interactions and attachments directly in the create payload.

Inline interactions

You can include an interactions array when creating a candidate.

  • Up to 10 interactions per candidate

  • Each interaction is validated against the interaction schema

  • Interactions are created atomically with the candidate

This is useful for:

  • Logging an initial intake call

  • Capturing a first contact moment

  • Registering signups to events

  • Importing historical interaction data

Inline interaction creation is only supported when creating candidates, not when updating them. You can add interactions to existing candidates with the POST /candidates/:id/interactions endpoint.

Inline attachments

Attachments can be included using:

  • curriculumVitae

  • otherAttachments

Each attachment can be provided as a public URL or Base64-encoded data (including data URI prefix).

Limits:

  • Maximum of 5 attachments per field

  • Attachments are uploaded and linked as part of the mutation

Inlining attachments is convenient when:

  • Submitting form uploads

  • Migrating candidate documents

  • Creating a fully populated candidate in one request

Mutation Engine response

All candidate creation endpoints are handled by the Mutation Engine. As a result, write operations are asynchronous.

What a 202 response means

A successful submission returns a 202 Accepted response, indicating that:

  • The request was validated successfully

  • The mutation was accepted and queued

  • Processing will happen asynchronously

{
	"statusCode": 202,
	"message": "The mutation request has been accepted for processing.",
	"data": {
		"status": "accepted",
		"idempotencyKey": "a_unique_key_generated_for_this_request_12345",
		"message": "The mutation request has been accepted for processing."
	},
	"meta": {
		"sandboxEnabled": false
	}
}

Important implications

  • A 202 response is not confirmation that the candidate exists yet

  • Treat the response as an acknowledgement, not a result

  • Use idempotencyKey to safely retry requests

  • Use callbackUrl to receive completion or failure notifications

Design your integration to be event-driven, not synchronous

Mutation Engine

The Mutation Engine is the system responsible for all write operations in our API.

Supported field values

Some fields only accept predefined values. The most important standardized options are listed below.

nieuw
matchen
oriënteren
voorbereiden
in opleiding
werkzaam
uitgestroomd
Primair onderwijs
Voortgezet onderwijs
Speciaal onderwijs
Middelbaar beroepsonderwijs
Hoger onderwijs
Praktijkonderwijs
Docent / leraar
Instructeur (mbo)
OOP
Ondersteuning
Leerlingenzorg
Midden management
Schoolleiding
Anders
Primair onderwijs
Beperkt tweedegraads
Tweedegraads
Eerstegraads
PDG
BKO/BDB
Kwalificatie onderwijs ondersteunend personeel
Kwalificatie Instructeur (MBO)
Geen: gastdocentschap
Pabo
Onbekend
Nog geen idee
Niet van toepassing
geen
praktijkonderwijs
vmbo-bl
vmbo-kl
vmbo-gl
vmbo-tl
vmbo
havo
vwo
mbo entree
mbo 2
mbo 3
mbo 4
mbo
associate degree
hbo propedeuse
hbo bachelor
hbo master
hbo
wo bachelor
wo master
wo
PhD
Nederlands
Engels
Wiskunde
Wiskunde A
Wiskunde B
Wiskunde C
Wiskunde D
Frans
Duits
Spaans
Latijnse taal en cultuur
Griekse taal en cultuur
Klassieke talen
KCV
Geschiedenis
Aardrijkskunde
Maatschappijleer
Maatschappijkunde
Maatschappijwetenschappen
Filosofie
Levensbeschouwing
Economie
Algemene economie
Bedrijfseconomie
Ondernemerschap - Academische vaardigheden
Natuurkunde
Scheikunde
Biologie
Rekenen
NLT (Natuur, leven en techniek)
Algemene Natuurwetenschappen
NaSk
Science
Life sciences
Informatica
Techniek
Technologie en toepassing
Toepassingsgericht onderwijs
Programmeren
installeren en energie
Produceren
installeren
energie (PIE)
Art en Technologie
Digital Creative Technology (DCT)
Digital Technology
Digitaal burgerschap
STEAM
T&T
CKV
Kunst & Techniek
Kunst: algemeen
Kunst: beeldend
Kunst: beeldend / tekenen
Kunst: dans
Kunst: drama
Kunst: podium
Kunst: tekenen
Kunst: theater
Kunstgeschiedenis/CKV
Handvaardigheid
Muziek
Vormgeving en media
Lichamelijke opvoeding
Lichamelijke opvoeding 2
Bewegen sport en maatschappij (BSM)
Dienstverlening en producten
Praktijkgericht programma (havo)
Praktijkprogramma zorg (mavo)
Zorg en welzijn
Mens en dienstverlening
Mens en Maatschappij
Mens en Natuur
Onderzoeken & Ontwerp
Onderzoekend leren
Onderzoeksvaardigheden
Millennium Skills
Global perspectives
Global citizenship
Big History
International Baccalaureate
Psychologie
Persoonlijke Vorming
PGP maatschappij
PGP P&O
PGP technologie
LOB/PWS
PWS
Zomer PWS
Leefstijl
Kennis van het geestelijk leven
Vrede en Recht
Wetenschap
Wetenschapsoriëntatie
Humaniora
Arabisch
Chinees
Italiaans
Russisch
NT2
Econasium
E&O
Telefonisch
E-mail
Persoonlijk
Anders
Doorverwijzing
Adviesgesprek
Kennismakingsgesprek
Inschrijving activiteit
Niet van toepassing

Always rely on the /schema endpoint for the complete and current list of allowed values.

Performance Considerations

To validate the payload when submitting a candidate, we must internally perform schema introspection for your region. The same performance limitations apply as when you call the /schema endpoint; Airtable’s database introspection is inherently slow.

Schema

The schema provides a complete overview of the shared candidate data model and the region-specific custom fields that apply to your education region.


If our system does not hit a valid cache entry, this introspection will take 3 - 6 seconds, which will directly affect the response time for your request.

This is not a problem we can solve with the Mutation Engine, since validation happens before a mutation in enqueued.

Field schema’s are cached for 72 hours.

Skipping Custom Field validation

If you payload does not include a customFields property, you can disable the schema introspection and validation entirely. To bypass the validation - which considerably improves performance if there is no cached schema - set the skipCustomFieldValidation flag in your requests query parameters.

This flag is supported for POST /candidates and POST /candidates/upsert.

Sandbox Support

All candidate creation endpoints support sandbox mode via:

  • The x-api-sandbox: true header, or

  • The /sandbox endpoint prefix

This allows you to test the candidate creation flows without affecting production data.