ā ļø This API is in beta. Endpoint shapes, event payloads, and behaviour may change before general availability. Breaking changes will be communicated to registered integrators in advance.
TDTA Client API - Overview#
The TDTA Client API lets agency integrators programmatically manage training bookings, discover upcoming sessions, send booking invites to candidates, and receive real-time webhook notifications for booking lifecycle events.Base URL: https://tdta.hbcompliance.co.uk/api/v1
Authentication#
All protected endpoints require a Bearer token in the Authorization header:Authorization: Bearer <access_token>
Obtain a token pair via POST /auth/token. Access tokens expire after 1 hour; use POST /auth/refresh (valid 7 days) to rotate without re-entering credentials.
All list endpoints return a consistent envelope:{
"data": [ ... ],
"meta": {
"current_page": 1,
"per_page": 20,
"last_page": 5,
"total": 98
},
"links": {
"next": "https://tdta.hbcompliance.co.uk/api/v1/bookings?page=2",
"prev": null
}
}
Rate Limiting#
60 requests per minute per IP. Exceeding this returns 429 Too Many Requests.
Errors#
| Status | Meaning |
|---|
401 | Missing or invalid bearer token |
404 | Resource not found or not owned by your account |
409 | Conflict (e.g. active hold already exists) |
422 | Validation failed or business rule violation |
429 | Rate limit exceeded |
500 | Server error ā contact support |
Webhooks#
Outbound webhook events are delivered to your registered endpoints via POST. All events share the same envelope:{
"event_id": "018f4a2b-1234-7000-8abc-def012345678",
"event_type": "booking.created",
"occurred_at": "2026-06-05T10:00:00+00:00",
"data": { ... }
}
Signature Verification#
Every request includes these headers:| Header | Description |
|---|
X-TDTA-Event | Event type, e.g. booking.created |
X-TDTA-Event-Id | UUID of the event ā use for idempotency |
X-TDTA-Delivery-Id | Numeric delivery attempt ID |
X-TDTA-Timestamp | Unix timestamp of dispatch (seconds) |
X-TDTA-Signature | sha256=<hmac> ā see below |
Computing the expected signature:signature = HMAC-SHA256(signing_secret, "{timestamp}.{raw_json_body}")
expected = "sha256=" + signature
Compare expected with X-TDTA-Signature using a constant-time comparison to prevent timing attacks. Reject requests where |now() - X-TDTA-Timestamp| > 300 (5-minute replay window).Retries#
Deliveries are retried up to 5 times with a 15-minute backoff on any non-2xx response or timeout. Return any 2xx status to acknowledge receipt.
For urgent issues affecting live bookings, email with the subject line [API URGENT] and include your hb_client_id and any relevant booking_id or event_id.