Waivers API
Waivers are liability and consent forms that customers sign before an activity. You write a waiver template, choose which products or sites it applies to, and customers sign it during or after booking. A waiver can be signed once per booking, or once per participant, with a guardian signing for minors.
For how staff manage waivers in the admin UI, see Waivers.
Customer endpoints
These endpoints need no login. Send your tenant ID in the x-tenant-id header.
| Method | Path | Description |
|---|---|---|
GET | /api/v1/waivers/active | The waiver template to show. |
POST | /api/v1/waivers/sign | Sign one waiver for a whole booking. |
GET | /api/v1/waivers/booking/{bookingId}/status | Whether a booking's waiver is signed. |
GET | /api/v1/waivers/booking/{bookingId}/participants/status | Waiver status for each participant in a booking. |
POST | /api/v1/waivers/booking/{bookingId}/participants/{participantId}/sign | Sign the waiver for one participant. |
The API records the signer's IP address and browser from the request. You do not send them.
Get the active template
GET /api/v1/waivers/active?locale=en&productId=p_demo
x-tenant-id: t_demo
Optional query parameters: locale, productId, siteId. The response is { "success": true, "data": { ...template } }, with the template's id, name, content, version, locale, isActive, requiresSignature, applicableFor and scopeIds.
Sign for a booking
POST /api/v1/waivers/sign
{
"bookingId": "bk_123",
"signedByEmail": "customer@example.com",
"signedByName": "Alex Example",
"signatureData": "data:image/png;base64,..."
}
| Field | Required | Description |
|---|---|---|
bookingId | Yes | The booking. |
signedByEmail | Yes | Signer's email. |
signedByName | Yes | Signer's name. |
signatureData | No | The drawn signature, as a base64 image. |
participantDob | No | Date of birth, ISO 8601. Used to detect a minor. |
guardianName | No | Guardian's name, when the signer is a minor. |
guardianEmail | No | Guardian's email, when the signer is a minor. |
Response:
{
"success": true,
"data": {
"signatureId": "ws_456",
"templateId": "wt_789",
"templateVersion": 2,
"signedAt": "2026-10-15T10:30:00.000Z",
"isMinor": false
},
"message": "Waiver signed successfully"
}
Check a booking's status
GET /api/v1/waivers/booking/{bookingId}/status
{
"success": true,
"data": {
"bookingId": "bk_123",
"requiresWaiver": true,
"isSigned": false,
"template": {
"id": "wt_789",
"name": "Activity waiver",
"version": 2,
"locale": "en"
}
}
}
When the waiver is signed, data has a signature object (id, signedByEmail, signedByName, signedAt) instead of the template to sign.
Per-participant status
GET /api/v1/waivers/booking/{bookingId}/participants/status
{
"success": true,
"data": {
"bookingId": "bk_123",
"requiresWaiver": true,
"allParticipantsSigned": false,
"participantCount": 2,
"signedCount": 1,
"pendingCount": 1,
"hasLegacySignature": false,
"participants": [
{
"participantId": "bp_1",
"participantName": "Alex Example",
"participantType": "adult",
"isMinor": false,
"requiresWaiver": true,
"isSigned": true,
"signatureId": "ws_456",
"signedAt": "2026-10-15T10:30:00.000Z",
"signedByEmail": "alex@example.com",
"signedByName": "Alex Example",
"isGuardianSignature": false
},
{
"participantId": "bp_2",
"participantName": "Sam Example",
"participantType": "child",
"isMinor": true,
"requiresWaiver": true,
"isSigned": false
}
]
}
}
hasLegacySignature is true when the booking was signed as a whole with POST /api/v1/waivers/sign. A booking without participant records returns an empty participants list; sign for the whole booking instead.
Sign for one participant
POST /api/v1/waivers/booking/{bookingId}/participants/{participantId}/sign
{
"participantId": "bp_2",
"signedByEmail": "alex@example.com",
"signedByName": "Alex Example",
"signatureData": "data:image/png;base64,...",
"isGuardianSignature": true,
"guardianRelationship": "parent"
}
| Field | Required | Description |
|---|---|---|
participantId | Yes | The same participant ID as in the path. |
signedByEmail | Yes | Signer's email. |
signedByName | Yes | Signer's name. |
signatureData | No | The drawn signature, as a base64 image. |
isGuardianSignature | No | true when a guardian signs. Required for a minor, or the request fails with 400. |
guardianRelationship | No | For example parent, guardian or legal_custodian. |
The response has the same shape as signing for a booking.
A participant is a minor when they are under 18, based on their age or date of birth on the booking.
Admin endpoints
Admin endpoints need a staff token. Template management needs admin:write; the compliance and audit reports need admin:read.
| Method | Path | Description |
|---|---|---|
GET | /api/v1/admin/waivers/templates | List templates. |
POST | /api/v1/admin/waivers/templates | Create a template. |
GET | /api/v1/admin/waivers/templates/{templateId} | Get a template. |
PATCH | /api/v1/admin/waivers/templates/{templateId} | Update a template. Content changes create a new version. |
POST | /api/v1/admin/waivers/templates/{templateId}/activate | Activate a template. |
POST | /api/v1/admin/waivers/templates/{templateId}/archive | Archive a template. Existing signatures stay valid. |
POST | /api/v1/admin/waivers/templates/{templateId}/clone | Copy a template. |
POST | /api/v1/admin/waivers/templates/bulk-update | Change several templates at once. |
GET | /api/v1/admin/waivers/templates/{templateId}/audit | A template's version and signature history. |
GET | /api/v1/admin/waivers/compliance | Signed and unsigned waivers across bookings. |
POST | /api/v1/admin/waivers/accept-on-behalf | Record a waiver accepted by phone or at the desk. |
Create a template
{
"name": "Activity waiver",
"content": "I understand and accept the risks of this activity...",
"locale": "en",
"requiresSignature": true,
"applicableFor": "specific_products",
"scopeIds": ["p_demo"]
}
| Field | Required | Description |
|---|---|---|
name | Yes | At least 3 characters. |
content | Yes | The waiver text, at least 10 characters. |
locale | No | Default en. |
requiresSignature | No | Default true. |
applicableFor | No | all (default), specific_products or specific_sites. |
scopeIds | With specific_* | The product or site IDs the template applies to. |
Errors
| Status | When |
|---|---|
400 | Invalid body, the participant has already signed, or a minor is signed without isGuardianSignature. |
404 | The booking, participant or template does not exist. |