Skip to main content
Use WaiverFile through Corsair: one client, typed API calls. Create the key in the WaiverFile admin under Settings > API > API keys; the same page shows the site ID. Every call needs that key and the site ID it belongs to, so store the pair in the key slot as <apiKey>\n<siteID> — the plugin splits it and reports a configuration error before any request if it is malformed.
  • Credentials travel in the query string, not a header. Every route takes apiKey and siteID as query parameters; there is no bearer token. The plugin adds both to every call, so a bare key is rejected up front rather than failing with an obscure 404.
  • InsertEvent is the exception. It carries the credentials in the body as APIKey and SiteID, which the plugin fills in from the same packed key. The query still holds them, but the body’s copy is what the route reads.
  • A bad key is usually a 400. Some malformed keys get a plain 401, but WaiverFile normally answers {"Message":"Invalid"} (or InvalidService… from Ping) with HTTP 400 for a wrong key or a site the key does not belong to — the same status as a genuine validation failure. The plugin reads the message to tell them apart, so a credential problem is reported as an auth error and a real 400 stays a validation error.
  • Errors have no code. The body is {"Message": "..."} with a capital M. There is nothing else to branch on, which is why the handlers rely on the status plus that one message.
  • A missing route is also a 404. Because everything is addressed by query parameter, a 404 means the path is wrong rather than the object missing — a misspelled endpoint reads exactly like a deleted waiver.
  • pageIndex conventions differ. The waiver lists (waivers.list, waivers.listLite) are zero-based and cap pageSize at 500. waivers.data is one-based and allows up to 1000. Getting this wrong silently returns the wrong page, so each schema documents and enforces its own.
  • consolidateParticipants is reserved. The API accepts it and ignores it; rows still come back one per participant.
  • Two deletes are not DELETE. events.delete is a GET /DeleteEvent and eventCategories.delete is a POST /DeleteEventCategory — so neither is safe to replay on a timeout, despite one looking like a read.
  • Three serialisations, one shape. Events, forms, categories and the site come back as serialised .NET objects (lowerCamelCase columns under me); the waiver reads come back as XML converted to JSON, with every value a string ("true", "0") and a single item sent as an object instead of an array; Ping, the counts and the webhook routes answer bare values. The plugin flattens all of them into the PascalCase names the reference uses (WaiverID, WaiverEventID, Name) and always returns lists as arrays. Participants on the waiver reads keep WaiverFile’s spelling Particpants; events.waivers uses standard JSON, so there they are Participants and booleans are real booleans.
  • events.inviteManagers always sends both optional parameters. The route 404s unless managerEmailMessage and skipSendingEmailIfAccountExists are present, so the plugin sends an empty message and false when they are omitted. With false, every address is emailed.
  • There is no single-event read. The v1 API has no GetEvent route; read an event through events.byDateRange, events.byCategory or the answer of the write you just made.
  • events.update replaces the attached forms. Omitting waiverFormIDs, or sending an empty list, attaches every active form; pass the event’s current form IDs to keep them. Send the empty GUID as eventCategoryID for no category.
  • The webhook triggers are path segments. Subscribing is POST /subscribe/<trigger>?targetUrl=… and unsubscribing is DELETE /deletesubscribe/<trigger> with the same URL, one route per trigger. The twelve triggers are newwaiver, newevent, newcheckin, newqrscan, newbookingcheckin, bookingcheckinundone, bookingcheckedin, newmembercheckin, membercheckinundone, editwaiver, editevent and editcheckin. There is no signing secret, so the receiving host verifies by its own means.
  • A waiver PDF is a file, not JSON. waivers.pdf downloads the bytes directly and returns them base64-encoded in content, with the content type and the real byte length.
  • A waiver holds personal data. Date of birth, email and phone are on the record, so the plugin never writes them to the event log. It does log identifiers (waiver, event and category IDs), counts, byte counts and flags, the site, event and category names, and a webhook target’s origin and path (never its query string). Error messages have the API key removed, because WaiverFile echoes the request URL in some error bodies.
What you get:
  • 31 typed API operations

Setup

1

Install

2

Add the plugin

corsair.ts
With multiTenancy: true, scope calls with corsair.withTenant(id). See Quick start for KEK + Hub keys, and Multi-tenancy for account isolation.
3

Choose authentication

4

Connect a tenant

Mint a connect link and send the tenant to it. Hub hosts the page and delivers the result to your app — see Connect / OAuth.

Example API calls

Read a signed waiver
Create an event
See the full list on the API page.

What’s next

API reference

Every waiverfile.api.* operation with input and output types.

Connect / OAuth

createLink, Hub delivery, and tenant connect flows.

Use with agents

Expose this plugin’s operations as MCP tools.