KiDig Partner API
Deutsche Version →

Partner API — Documentation

Version 0.2.0 · Machine-readable specification: openapi.yaml (OpenAPI 3.1)

Status: Endpoints, authentication and response conventions reflect the v1 target state: OAuth2 client registry, facility-side consent grants, full access auditing. This environment is staging with demo data; production starts once agreed.

Overview

The KiDig Partner API provides facility master data to integration partners. Core principle: a facility only becomes accessible after its management has activated the partner connection inside KiDig (the grant). This grant is verified server-side on every request — a valid token alone is not sufficient.

All responses are JSON, field names are English, dates follow ISO 8601. The API is versioned under /v1/; new optional fields may be added at any time and must be ignored by clients. Every successful data fetch is recorded in the respective facility's audit trail with your system as the actor.

Authentication

OAuth2 client credentials: request an access token with your client_id and client_secret. Tokens are valid for 30 minutes and are sent as an Authorization: Bearer header.

curl -X POST https://api-staging.kidig-online.de/v1/oauth/token \
  -H 'Content-Type: application/json' \
  -d '{
        "grant_type": "client_credentials",
        "client_id": "YOUR_CLIENT_ID",
        "client_secret": "YOUR_CLIENT_SECRET"
      }'

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIs…",
  "token_type": "Bearer",
  "expires_in": 1800,
  "scope": "facility:read"
}

Token endpoint errors follow RFC 6749: 401 {"error":"invalid_client"} for wrong credentials, 400 {"error":"unsupported_grant_type"} for any other grant_type.

List facilities

GET/v1/facilities

Returns every facility that currently grants your system access — no IDs need to be exchanged out of band. The externalFacilityId field carries the pairing code the facility manager entered at consent: your key for matching the facility to your own records. Revoked facilities disappear from the list immediately.

{
  "facilities": [
    {
      "id": "9a261ab8-06f6-4ff7-b4b2-ed0995b2daf9",
      "name": "Kindergarten Gartenkind",
      "externalFacilityId": "KRZ-4711",
      "grantedAt": "2026-08-20T14:32:10.000Z"
    }
  ]
}

Recommended sync: poll this list nightly (with ETag), match new entries, then fetch each facility's details. Every detail fetch is recorded in the facility's audit trail.

Fetch a facility

GET/v1/facilities/{facilityId}

curl https://api-staging.kidig-online.de/v1/facilities/9a261ab8-06f6-4ff7-b4b2-ed0995b2daf9 \
  -H "Authorization: Bearer $TOKEN"
{
  "id": "9a261ab8-06f6-4ff7-b4b2-ed0995b2daf9",
  "name": "Kindergarten Gartenkind",
  "address": {
    "street": "Bienemajastraße 5",
    "zipCode": "79123",
    "town": "Marktfrühstück"
  },
  "country": "DE",
  "federalState": "BW"
}
FieldMeaning
idKiDig UUID of the facility
nameFacility name
address.streetStreet and house number (may be null)
address.zipCode, address.townPostal code and town (may be null)
countryISO 3166-1 alpha-2, e.g. DE
federalStateGerman federal state code, e.g. BW. KiDig computes public holidays from this itself — partners must not send or derive holidays.

Error format

All errors (except at the token endpoint and for 429, see below) use RFC 7807 application/problem+json:

{
  "type": "https://api.kidig-online.de/problems/no-grant",
  "title": "No active grant for this facility",
  "status": 403,
  "requestId": "8e60828b-e7e0-4258-af83-d389a0f5a6ca"
}
StatusMeaning
400facilityId is not a UUID
401Token missing, invalid or expired → request a new token
403No active grant for this facility (or the facility revoked its grant)
404Facility does not exist
429Rate limit reached. This response comes directly from the upstream limiter and has no problem+json body and no X-Request-Id — back off briefly and retry

Important for your error handling: 401 means "token problem on your side", 403 means "the facility has not (or no longer) granted access". Please treat the two cases separately.

Caching & polling

Master data changes rarely. The recommended sync pattern is nightly polling with ETags:

  1. Store the ETag header of every 200 response.
  2. Send If-None-Match: "<etag>" on the next fetch.
  3. Unchanged → 304 Not Modified with no body. Changed → 200 with a new ETag; compute the difference against your last known state.
curl -i https://…/v1/facilities/{id} \
  -H "Authorization: Bearer $TOKEN" \
  -H 'If-None-Match: "01e5ac7f0c34227087f77a6a9f353c5a"'

Headers & support

Every response carries an X-Request-Id header (errors additionally include it as requestId in the body). Please quote this id in support enquiries — it lets us trace the exact request in our logs.

Rate limits

Currently 5 requests per second per IP; the token endpoint is additionally limited to 10 requests per minute per IP (tokens are valid for 30 minutes — please reuse them). A per-partner quota is planned for production; please spread bulk synchronisation over time (e.g. nightly, sequential).

Versioning

Breaking changes only appear under a new path prefix (/v2/). Within /v1/: new endpoints, new optional fields and new enum values may appear at any time — clients must ignore unknown fields and values.