Skip to main content

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.

MethodPathDescription
GET/api/v1/waivers/activeThe waiver template to show.
POST/api/v1/waivers/signSign one waiver for a whole booking.
GET/api/v1/waivers/booking/{bookingId}/statusWhether a booking's waiver is signed.
GET/api/v1/waivers/booking/{bookingId}/participants/statusWaiver status for each participant in a booking.
POST/api/v1/waivers/booking/{bookingId}/participants/{participantId}/signSign 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,..."
}
FieldRequiredDescription
bookingIdYesThe booking.
signedByEmailYesSigner's email.
signedByNameYesSigner's name.
signatureDataNoThe drawn signature, as a base64 image.
participantDobNoDate of birth, ISO 8601. Used to detect a minor.
guardianNameNoGuardian's name, when the signer is a minor.
guardianEmailNoGuardian'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"
}
FieldRequiredDescription
participantIdYesThe same participant ID as in the path.
signedByEmailYesSigner's email.
signedByNameYesSigner's name.
signatureDataNoThe drawn signature, as a base64 image.
isGuardianSignatureNotrue when a guardian signs. Required for a minor, or the request fails with 400.
guardianRelationshipNoFor 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.

MethodPathDescription
GET/api/v1/admin/waivers/templatesList templates.
POST/api/v1/admin/waivers/templatesCreate 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}/activateActivate a template.
POST/api/v1/admin/waivers/templates/{templateId}/archiveArchive a template. Existing signatures stay valid.
POST/api/v1/admin/waivers/templates/{templateId}/cloneCopy a template.
POST/api/v1/admin/waivers/templates/bulk-updateChange several templates at once.
GET/api/v1/admin/waivers/templates/{templateId}/auditA template's version and signature history.
GET/api/v1/admin/waivers/complianceSigned and unsigned waivers across bookings.
POST/api/v1/admin/waivers/accept-on-behalfRecord 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"]
}
FieldRequiredDescription
nameYesAt least 3 characters.
contentYesThe waiver text, at least 10 characters.
localeNoDefault en.
requiresSignatureNoDefault true.
applicableForNoall (default), specific_products or specific_sites.
scopeIdsWith specific_*The product or site IDs the template applies to.

Errors​

StatusWhen
400Invalid body, the participant has already signed, or a minor is signed without isGuardianSignature.
404The booking, participant or template does not exist.