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/schemaresponse 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 EngineHow 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 |
|
|
|
|
|
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 |
|
|
|
|
|
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
/sandboxinstead of/v2. Example:https://onderwijsregio.onderwijsin.nl/api/sandbox/schema -
Set the
x-api-sandboxheader totrue
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.