Skip to main content

Consent Tracking

Track who still needs to sign a waiver or form, see the full per-participant timeline (requested, opened, each reminder with delivery status, signed, counter-signed), and chase the unsigned โ€” for one person, one booking, or many bookings at once.

All endpoints read the same resolver the EquipDash portal uses, so the API can never disagree with the Consent tracker screen or the booking's Consents card.

Every upcoming live booking that still has an outstanding consent, soonest booking first.

GET /v1/consent-tracker

Requires the bookings:read scope.

Query Parametersโ€‹

ParameterTypeDescription
daysintegerOnly bookings starting within the next N days
date_fromdate (YYYY-MM-DD)Booking-date window start (supplier-local day). The tracker never shows past bookings regardless of the range.
date_todate (YYYY-MM-DD)Booking-date window end (supplier-local day)
form_idintegerOnly outstanding signatures for this form
onlystringnobody_signed or chase_exhausted
searchstringBooking id, customer or group name
limitintegerMax rows per page (default 100, max 200)
offsetintegerRows to skip before the page starts (default 0). Page with limit + offset until you have total_count rows.

Response (200 OK)โ€‹

{
"data": {
"bookings": [
{
"booking_id": 123,
"display_name": "Jane Doe",
"booking_type": "rental",
"start_date": "2026-08-12T16:00:00.000000Z",
"signed": 1,
"required": 3,
"outstanding": 2,
"opened_not_signed": 1,
"next_reminder_at": "2026-08-09T14:00:00.000000Z",
"next_attempt_number": 2,
"max_attempts": 3,
"chase_exhausted": false,
"nobody_signed": false,
"reminders_enabled": true
}
],
"total_count": 1
}
}

The ordered per-participant event list โ€” what was sent, whether it was opened, each reminder with its delivery status, what happens next, and the signature (with signed-on-behalf provenance and counter-signatures).

GET /v1/bookings/{id}/consent-timeline

Requires the bookings:read scope. This is also how to read per-participant consent status for a program cohort's enrollments or a session manifest: call it per booking id.

Chase one booking (or one participant)โ€‹

Runs the same engine as the scheduled chaser: it counts as an attempt, respects the attempt cap, and lands on the timeline like any other send. The 8amโ€“8pm supplier-local send window is NOT applied here โ€” quiet hours govern the automatic chaser only, so this endpoint sends immediately whatever the local clock says.

POST /v1/bookings/{id}/chase-consents

Requires the bookings:write scope.

Body Parametersโ€‹

ParameterTypeDescription
customer_idinteger (optional)Chase only this participant's unsigned forms. Omit to chase everyone on the booking who still hasn't signed.

Success (200 OK)โ€‹

{
"data": {
"message": "Reminder sent to everyone on this booking who still hasn't signed.",
"pairs_chased": 2
}
}

No reminder sent (422)โ€‹

{
"error": {
"code": "no_reminder_sent",
"message": "No reminder is due yet. The last one went out recently."
}
}

Bulk chaseโ€‹

Chase several bookings in one call โ€” the API twin of the tracker's bulk "Send reminders" action. Each booking runs through the same engine; bookings with nothing due simply report their reason.

POST /v1/bookings/chase-consents

Requires the bookings:write scope.

Body Parametersโ€‹

ParameterTypeDescription
booking_idsinteger[]1โ€“100 booking ids to chase

Success (200 OK)โ€‹

{
"data": {
"bookings_chased": 2,
"results": [
{ "booking_id": 123, "sent": true, "reason": null, "pairs_chased": 2 },
{ "booking_id": 124, "sent": false, "reason": "nothing_unsigned", "pairs_chased": 0 },
{ "booking_id": 999, "sent": false, "reason": "not_found" }
]
}
}

Ids that don't belong to your account report not_found โ€” they are never chased and never leak.

A draft booking reports draft and is not chased.

Example Requestโ€‹

curl -X POST "https://app.equipdash.com/api/v1/bookings/chase-consents" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"booking_ids": [123, 124]}'

Errorsโ€‹

StatusCodeDescription
401authentication_requiredNo API key provided
401invalid_api_keyInvalid API key
403insufficient_scopeAPI key lacks the required scope
403forbiddenBooking belongs to another supplier
404not_foundBooking not found
422DRAFT_NOT_CONFIRMEDThe booking is a draft. Confirm it before sending
422no_reminder_sentSwitched off, not live, all signed, limit reached, or a reminder went out in the last 15 minutes