Skip to content

Certificates

The Certificates API lets you manage user certificates and qualifications (e.g. safety courses, builder cards, crane licenses) from an external competence or HR system, so site managers in Ditio can see at a glance who is qualified for what — and when a certificate expires. Certificates are matched to users by employee number.

Base URL: api/v4/integration/certificates · Scope: ditioapiv3

Terminal window
# Test (default for all examples)
export DITIO_API_BASE="https://core-api.ditio.dev/core"
# Production: export DITIO_API_BASE="https://core-api.ditio.app/core"
POST /api/v4/integration/certificates

Send an array of certificates. The operation is an upsert: if a certificate already exists for the employee (matched by employee number + certificate type), it is updated; otherwise a new one is created. This makes the endpoint safe to call repeatedly from a scheduled sync.

Terminal window
curl -X POST "$DITIO_API_BASE/api/v4/integration/certificates" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"employeeNumber": "1042",
"certificateType": "Byggekort",
"certificateNumber": "BK-2026-12345",
"issuedDateTime": "2026-01-15T00:00:00Z",
"validUntilDateTime": "2028-01-15T00:00:00Z",
"notes": "Utstedt av opplæringskontoret"
},
{
"employeeNumber": "1042",
"certificateType": "Kranførerbevis",
"certificateNumber": "KF-2026-67890",
"issuedDateTime": "2025-06-01T00:00:00Z",
"validUntilDateTime": "2027-06-01T00:00:00Z"
}
]'
FieldTypeRequiredDescription
employeeNumberstringYesMust match an existing employee in Ditio
certificateTypestringYesType of certificate (e.g. “Byggekort”, “Kranførerbevis”)
issuedDateTimedatetimeYesDate the certificate was issued
validUntilDateTimedatetimeYesExpiration date
certificateNumberstringNoCertificate number / ID
notesstringNoAdditional notes
  • employeeNumber must match an existing user in your company
  • issuedDateTime must be before validUntilDateTime
  • If a certificate with the same employeeNumber + certificateType already exists, it is updated rather than duplicated

Python example — sync from a competence system

Section titled “Python example — sync from a competence system”
import os
import requests
API_BASE = os.environ.get("DITIO_API_BASE", "https://core-api.ditio.dev/core")
certificates = [
{
"employeeNumber": "1042",
"certificateType": "Byggekort",
"certificateNumber": "BK-2026-12345",
"issuedDateTime": "2026-01-15T00:00:00Z",
"validUntilDateTime": "2028-01-15T00:00:00Z",
},
]
response = requests.post(
f"{API_BASE}/api/v4/integration/certificates",
headers={"Authorization": f"Bearer {token}"},
json=certificates,
)
response.raise_for_status()
IssueCauseFix
400 for one entryemployeeNumber doesn’t match a Ditio userCreate the user first via Users or Employees v5
400 on datesissuedDateTime after validUntilDateTimeCheck for swapped fields in your mapping
Duplicates appearingCertificate type spelled differently between syncsKeep certificateType values stable — the upsert matches on the exact string