Je hebt Javascript nodig om deze website te kunnen gebruiken. Pas je browserinstellingen in om verder te gaan!
Candidates

Submitting candidates

Create or upsert candidates, including interactions and attachments, through the asynchronous Mutation Engine.

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.

Read the schema guide before creating a payload.

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 interactions, attachments, and custom fields.
  • Is processed asynchronously by the Mutation Engine.
  • Returns 202 Accepted.

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 exists, it is updated.
  • Otherwise, the API creates a new candidate.

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
response.json
{
    "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 does not confirm that the candidate exists yet.
  • Treat the response as an acknowledgement, not a result.
  • Use idempotencyKey to retry safely.
  • Use callbackUrl for completion and failure notifications.

Design your integration to be event-driven, not synchronous

Read the Mutation Engine guide to understand asynchronous processing.

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

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

Consider schema-validation performance

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.

Read the schema guide for the complete field model.

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.

The Mutation Engine cannot avoid this delay because validation happens before a mutation is queued.

Field schemas are cached for 72 hours.

Skipping Custom Field validation

If your payload does not include customFields, set skipCustomFieldValidation in the request query parameters to skip schema introspection and validation. This can significantly improve performance without a cached schema.

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

Test in the sandbox

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.

Keep in touch with the latest

Sign up for our monthly deep dives - straight to your inbox.