Migration Guide

A step by step checklist for migrating from version 1 to version 2.

Even though this is a major release, most migrations are straightforward.
If your integration only submits new candidates, upgrading typically takes less than 10 minutes.

Who this guide is for

This guide is intended for developers migrating an existing v1 integration to v2.

Migration effort depends on your use case:

  • Easy (~10 minutes)
    You only create new candidates and don’t rely on v1 schema parsing.

  • Moderate (~30 - 60 minutes)
    You update candidates, submit interactions, or dynamically map fields.

  • Advanced (1 - 2+ hours)
    You generate forms or validation logic from the v1 /schema response or assume synchronous writes.

Overview

Version 2 introduces many new features with only a small number of breaking changes. Most breaking changes are the result of stricter naming conventions and can be resolved by updating property names.

The most important conceptual change—though not strictly breaking—is the introduction of the Mutation Engine. All write operations are now asynchronous. Integrating this properly may require small changes to your application flow.

We strongly recommend reviewing the Mutation Engine documentation before starting your migration.

Mutation Engine

How our mutation engine works, and what to expect from it.

⚠️ Important: asynchronous writes

All create, update, and delete operations in v2:

  • Return 202 Accepted

  • Are processed asynchronously

  • Are finalized via callbacks or eventual consistency

If your v1 integration assumed immediate write results, you must update your logic.

Mandatory steps

Complete all steps in this section to avoid breaking changes in your application.

1. Change the Base URL

The new API is accessible at:

https://onderwijsregio.onderwijsin.nl/api/v2

All endpoints referenced in the documentation are relative to this base URL.

Change the Authentication Header

The old api-key header is deprecated. Use the x-api-key header instead.

Mapping of Candidate Field Keys

The field names in the candidate schema have been translated from Dutch to English, along with several additional standardization changes.

From version 1.1 onward, the /create-user endpoint returned the newly created record exactly as defined in Airtable, using Airtable’s record field keys. These keys differed from the field keys returned by the /schema endpoint.

In version 2, all field keys have been fully standardized for both input and output. This ensures consistency across endpoints.

Refer to the table below for the new field key mappings.

v1

Airtable (v1)

v2

naam

Naam

name

email

Email

email

privacy_consent

Privacy Consent

privacyConsent

telefoon

Telefoon

phone

fase

Fase

phase

sector

Sector voorkeur

sectorPreferences

functie

Functie voorkeur

rolePreferences

kwalificatie

Gewenste kwalificatie

desiredQualifications

vooropleiding

Vooropleiding

priorEducation

-

-

subjectPreferences

linkedin

LinkedIn

linkedin

geboortedatum

Geboortedatum

dateOfBirth

motivatie

Motivatie

motivation

adres

Adres

address

plaats

Plaatsnaam

city

postcode

Postcode

postalCode

-

-

curriculumVitae

-

-

otherAttachments

interacties

interacties

interactions

interactie

interacties

deprecated

custom_fields

-

customFields

Custom Fields
Due to their dynamic, user-generated nature, custom fields (contained within the customFields array) have not been renamed. As a result, naming conventions cannot be enforced for these fields.

As in version 1, you should introspect the (custom) fields schema via the /schema endpoint to retrieve the available custom field mappings.

Mapping on Interaction Field Keys

Similar to the candidate schema, the field keys for interactions have also been renamed and standardized in version 2.

Refer to the table below for the updated interaction field mappings.

v1

Airtable (v1)

v2

datum

Uitgevoerd op

performedAt

soort

Soort

type

samenvatting

Samenvatting

summary

-

Notities

notes

-

Duur

duration

New Custom Fields interface

Custom fields are now modeled as a nested JSON Schema object under customFields.

They:

  • Use the same JSON Schema constructs as shared fields

  • Are region-specific and dynamically generated

  • Must always be discovered via /schema

  • Are validated only when known (see custom field validation behavior)

This replaces the legacy objectArray-based custom field modeling from v1.

Checklist

  • Change the Base URL

  • Change the Authentication Header

  • Change mapping of candidate field keys

  • Change mapping on interaction field keys

  • Change interface of custom fields


Optional steps

These steps are optional but recommended to take advantage of new features and improvements.

Schema Interface Changes

In version 2, the /schema endpoint has been fundamentally redesigned.

While the goal of the endpoint remains the same—describing which candidate payloads are accepted—the schema is no longer a custom, proprietary format. Instead, it now returns a fully standards-compliant JSON Schema that directly mirrors API validation.

This is one of the most important improvements in v2.

This section highlights the most important differences and what you need to adapt when migrating from v1 to v2.

High-level Overview

In v1, the /schema endpoint returned a custom field-description format that required client-side interpretation.

In v2, the /schema endpoint returns:

  • A standards-compliant JSON Schema document

  • Fully compatible with OpenAPI

  • Generated directly from the API’s Zod validation schemas

  • Guaranteed to stay in sync with runtime validation

There is no longer any difference between:

  • What the schema describes

  • What the API accepts

  • What the API validates

Clients that rely on the /schema response for validation, form generation, or dynamic payload construction must update their schema parsing logic when upgrading to v2.

Old schema (v1)

In version 1, the schema:

  • Used a custom structure (fieldName, fieldType, options, etc.)

  • Required clients to interpret field semantics manually

  • Modeled nested data using ad-hoc conventions (objectArray)

  • Was not directly usable with JSON Schema or OpenAPI tooling

  • Could drift from actual API validation logic

Example characteristics:

  • Types expressed as loose strings

  • Required fields inferred rather than enforced

  • No formal validation rules (patterns, formats, unions)

  • Limited tooling support

New schema (v2)

In version 2, the /schema endpoint returns a complete JSON Schema document.

Key properties:

  • Uses standard JSON Schema keywords:

    • type

    • properties

    • required

    • enum

    • format

    • oneOf / anyOf

    • additionalProperties

  • Explicitly defines:

    • Required vs optional fields

    • Allowed values

    • Nested object and array structures

  • Fully compatible with:

    • OpenAPI tooling

    • JSON Schema validators

    • Form generators

    • AI structured-output systems

The schema is generated using Zod’s native JSON Schema support: https://zod.dev/json-schema. You can create your own validation logic by using the z.fromJSONSchema() method.

This ensures the schema is authoritative and cannot drift from API validation.

Integrate the Sandbox Environment

For non-production environments, you can now use the sandbox environment. The sandbox provides access to the same API features as production but is fully isolated from production data. You can use the same API keys as usual.

To enable the sandbox, use one of the following approaches:

  • Prefix the endpoint with /sandbox instead of /v2. Example:

    https://onderwijsregio.onderwijsin.nl/api/sandbox/schema
  • Set the x-api-sandbox header to true

Explore the new endpoints in the API Explorer

Version 2 introduces dozes of new endpoints you can use in your application. You can explore, inspect and test them in the interactive API Reference.