Hiretime SSO Documentatie
Welkom bij de ontwikkelaars- en integratiedocumentatie van Hiretime. Deze handleiding legt stap voor stap uit hoe u uw leerling- en medewerkersgegevens (SIS / HRIS) veilig kunt synchroniseren met ons platform via de Open Education API (OEAPI v6.0) of het Edu-V (v1.1.0) protocol.
1. Overzicht & Architectuur
Via SSO stelt Hiretime onderwijsinstellingen en zakelijke klanten in staat om studenten, docenten, klassen en groepslidmaatschappen vooraf in ons systeem klaar te zetten. Hierdoor worden gebruikers direct bij hun eerste Single Sign-On (SSO) login aan de juiste organisatie en klassen gekoppeld.
Belangrijkste voordelen:
- Geautomatiseerde synchronisatie van student- en docentgegevens.
- Ondersteuning voor standaard onderwijsprotocollen (OEAPI v6.0 en Edu-V v1.1.0).
- Ondersteuning voor asynchrone batchverwerking voor optimale schaalbaarheid.
- Veilige asymmetrische sleutelauthenticatie (EdDSA / Ed25519 JWT tokens).
2. Authenticatie & JWT Signing
Wanneer er een API Key voor uw organisatie wordt aangemaakt in het Hiretime Dashboard, ontvangt u een uitnodigingsmail met uw Company ID (cid), Key ID (kid), de vereiste claims en een beveiligde eenmalige link om uw Private Key in te zien. Om veiligheidsredenen wordt de private key nooit per e-mail verzonden en kan deze slechts éénmalig worden bekeken. Sla de private key direct veilig op in uw eigen sleutelbeheer (KMS / Key Vault).
Authenticatiestappen:
-
Genereer een JWT (JSON Web Token): Onderteken elk API-verzoek met een cryptografisch JWT token op basis van het
EdDSA(Ed25519) algoritme met behulp van uw private key. -
Verplichte Claims in de JWT Payload:
cid: Uw unieke Company ID (bijv.oXpL0ex3Q1jaPvo8eeLQ).kid: Uw unieke Key ID (bijv.oZBTEYDs4ArVv33dNoQa).iss: Uw e-mailadres (de issuer, zoals vermeld in de uitnodigingsmail).exp: Expiratietijd (aanbevolen: maximaal 15 minuten tot 1 uur geldig).iat: Tijdstip van uitgifte (Unix epoch timestamp in seconden).
-
Stuur de Authorization Header mee:
Voeg het gegenereerde token toe aan het HTTP-verzoek via de header:
Authorization: Bearer <uw_gegenereerde_jwt_token>
Voorbeeld JWT Header & Payload
{
"alg": "EdDSA",
"typ": "JWT"
}
{
"cid": "oXpL0ex3Q1jaPvo8eeLQ",
"kid": "oZBTEYDs4ArVv33dNoQa",
"iss": "ict-beheerder@school.nl",
"iat": 1726000000,
"exp": 1726003600
}
Voorbeeld JWT Generatie Code (Node.js & Python)
const crypto = require('crypto');
const fs = require('fs');
// 32-byte raw Ed25519 private key in base64
const privateKeyB64 = fs.readFileSync('./private_key.pem', 'utf8').trim();
const rawPrivKey = Buffer.from(privateKeyB64, 'base64');
const pkcs8Header = Buffer.from('302e020100300506032b657004220420', 'hex');
const pkcs8Key = Buffer.concat([pkcs8Header, rawPrivKey]);
const privateKey = crypto.createPrivateKey({
key: pkcs8Key,
format: 'der',
type: 'pkcs8'
});
function base64Url(input) {
return Buffer.from(input).toString('base64url');
}
const now = Math.floor(Date.now() / 1000);
const header = { alg: 'EdDSA', typ: 'JWT' };
const payload = {
cid: 'YOUR_COMPANY_ID',
kid: 'YOUR_KEY_ID',
iss: 'YOUR_EMAIL_ADDRESS',
iat: now,
exp: now + 3600
};
const encodedHeader = base64Url(JSON.stringify(header));
const encodedPayload = base64Url(JSON.stringify(payload));
const dataToSign = Buffer.from(`${encodedHeader}.${encodedPayload}`);
const signature = crypto.sign(null, dataToSign, privateKey);
const token = `${encodedHeader}.${encodedPayload}.${base64Url(signature)}`;
console.log('Authorization: Bearer ' + token);
import base64
import time
import jwt
from cryptography.hazmat.primitives.asymmetric import ed25519
# 32-byte raw Ed25519 private key in base64
with open('private_key.pem', 'r') as f:
raw_key = base64.b64decode(f.read().strip())
private_key = ed25519.Ed25519PrivateKey.from_private_bytes(raw_key)
now = int(time.time())
payload = {
'cid': 'YOUR_COMPANY_ID',
'kid': 'YOUR_KEY_ID',
'iss': 'YOUR_EMAIL_ADDRESS',
'iat': now,
'exp': now + 3600
}
token = jwt.encode(payload, private_key, algorithm='EdDSA')
print(f"Authorization: Bearer {token}")
3. Ondersteunde Protocollen (OEAPI & Edu-V)
De Hiretime API biedt volledige ondersteuning voor twee vooraanstaande standaarden op het gebied van onderwijs- en persoonsgegevensuitwisseling:
Open Education API (OOAPI / OEAPI v6.0)
OEAPI is de landelijke SURF-standaard voor hoger- en mbo-onderwijs in Nederland. Het protocol maakt gebruik van gestandaardiseerde datamodellen voor personen (studenten/docenten), groepen (klassen) en memberships (groepskoppelingen).
In de Hiretime API stuurt u verzoeken naar de OEAPI endpoints met payloads die direct matchen met de OEAPI schema's:
-
Personen:
personId,email,givenName,surname. - Groepen:
groupId,name(meertalige array). -
Memberships:
personId,groupId,role,state.
4. API Endpoints & Request Structuur
Alle API-verzoeken dienen verzonden te worden naar de basishost https://sso.hiretime.nl met Content-Type
application/json.
Generieke Request Wrapper: Elk import endpoint verwacht een JSON object met companyId, optioneel
syncId (voor sessietracering) en een data array met de specifieke entiteiten:
{
"companyId": "YOUR_COMPANY_ID",
"syncId": "optional-uuid-v4-session-id",
"data": [ ... ]
}
OEAPI Endpoints (v6.0)
| Methode | Endpoint | Omschrijving |
|---|---|---|
| POST | /v1/oeapi/imports/students |
Importeer of synchroniseer studenten via OEAPI persoonsstructuur. |
| POST | /v1/oeapi/imports/teachers |
Importeer of synchroniseer docenten via OEAPI persoonsstructuur. |
| POST | /v1/oeapi/imports/classes |
Importeer groepen / klassen via OEAPI groepsstructuur. |
| POST | /v1/oeapi/imports/memberships |
Importeer koppelingsgegevens tussen personen en groepen. |
Voorbeeld Request Payload (OEAPI Studenten):
POST /v1/oeapi/imports/students
Authorization: Bearer <jwt_token>
Content-Type: application/json
{
"companyId": "oXpL0ex3Q1jaPvo8eeLQ",
"syncId": "c0a80101-0000-1000-8000-000000000001",
"data": [
{
"personId": "s1234567",
"givenName": "Jan",
"surname": "De Vries",
"email": "j.devries@student.roc.nl"
},
{
"personId": "s7654321",
"givenName": "Sanne",
"surname": "Bakker",
"email": "s.bakker@student.roc.nl"
}
]
}
Edu-V Endpoints (v1.1.0)
| Methode | Endpoint | Omschrijving |
|---|---|---|
| POST | /v1/eduv/imports/students |
Importeer studenten via Edu-V Students API formaat. |
| POST | /v1/eduv/imports/teachers |
Importeer medewerkers/docenten via Edu-V Employees API formaat. |
| POST | /v1/eduv/imports/classes |
Importeer groepen via Edu-V Group structuur. |
| POST | /v1/eduv/imports/memberships |
Importeer groepslidmaatschappen of lesroostertoewijzingen. |
Voorbeeld Request Payload (Edu-V Studenten):
POST /v1/eduv/imports/students
Authorization: Bearer <jwt_token>
Content-Type: application/json
{
"companyId": "oXpL0ex3Q1jaPvo8eeLQ",
"syncId": "c0a80101-0000-1000-8000-000000000001",
"data": [
{
"userMasterIdentifier": "eck-1001",
"userIds": [
{ "userId": "s1234567", "userIdType": "studentNumber" }
],
"givenName": "Jan",
"familyName": "De Vries",
"email": "j.devries@student.roc.nl",
"status": "active",
"dateCreated": 1768464000000000,
"dateLastModified": 1778500800000000
}
]
}
Voorbeeld Request Payload (Edu-V Docenten):
POST /v1/eduv/imports/teachers
Authorization: Bearer <jwt_token>
Content-Type: application/json
{
"companyId": "oXpL0ex3Q1jaPvo8eeLQ",
"syncId": "c0a80101-0000-1000-8000-000000000001",
"data": [
{
"userIds": [
{ "userId": "emp_9901", "userIdType": "employeeNumber" }
],
"givenName": "Maria",
"familyName": "Jansen",
"email": "m.jansen@roc.nl",
"status": "active",
"dateCreated": 1768464000000000,
"dateLastModified": 1778500800000000
}
]
}
Opmerking over Edu-V velden: Het veld status ('active') is verplicht. Tijdstempels zoals
dateCreated en dateLastModified worden meegegeven als Unix microseconden (UTC) of ISO 8601 strings. Identificaties binnen
userIds maken gebruik van userIdType (bijv. studentNumber of employeeNumber).
5. Job Status & Error Monitoring
Aangezien importbatches asynchroon verwerkt worden, geeft het import endpoint direct een ImportJob
reactie terug met een unieke jobId en de initiële status pending.
Response Voorbeeld op Import Call:
HTTP/1.1 200 OK
Content-Type: application/json
{
"jobId": "job_987654321_abc",
"companyId": "oXpL0ex3Q1jaPvo8eeLQ",
"status": "pending",
"totalRecords": 2,
"processedRecords": 0,
"errors": [],
"createdAt": "2026-09-10T09:00:00.000Z"
}
Status Opvragen
Gebruik onderstaand endpoint om de voortgang van de import job te monitoren:
GET /v1/imports/status/<jobId>
Authorization: Bearer <jwt_token>
Mogelijke statussen:
pending: De job is in de wachtrij geplaatst.processing: De records worden verwerkt en gesynchroniseerd.completed: De import is succesvol afgerond.failed: Er is een fout opgetreden tijdens het verwerken.
Fouten Inzien
Indien een job status failed heeft of er specifieke recordfouten zijn opgetreden, vraagt u de foutenreeks op via:
GET /v1/imports/status/<jobId>/errors
Authorization: Bearer <jwt_token>
Voorbeeld Error Response:
{
"jobId": "job_987654321_abc",
"errors": [
"Record 1 (s1234567): Ongeldig e-mailadres formaat.",
"Record 2 (s7654321): Groep 'grp_99' niet gevonden."
]
}
6. Specificaties & Ondersteuning
Raadpleeg de officiële specificaties voor aanvullende details over het OEAPI en Edu-V afsprakenstelsel:
Open Education API Specification (v6.0)
Officiële SURF OOAPI/OEAPI specificaties en datamodellen.
Edu-V Afsprakenstelsel (v1.1.0)
Documentatie voor Students, Employees en Association API's.
Hulp of Vragen?
Ons technische ondersteuningsteam staat voor u klaar bij het opzetten en testen van uw SSO import koppeling.
E-mail: support@hiretime.nl