Put attendance on your chapter website, sync members with your own tools, or get a webhook the moment someone taps. A REST API and signed webhooks, part of Plus, turned on per organization after a quick review.
Request API accessEvery request goes to https://checkerd.com/api/v1 with your key as a Bearer token. Bodies and responses are JSON. Times are ISO 8601 (send an offset, like -05:00).
Call it from your server, never from a web page. Keys can read member phone numbers and emails, so the API doesn't accept calls from browsers. A website shows data by fetching it on its server.
Lists return data and next_cursor. Pass ?cursor= for the next page and ?limit= (1–100, default 50) for the page size.
curl https://checkerd.com/api/v1/me \
-H "Authorization: Bearer ck_live_…"Check someone in from your own appcurl -X POST https://checkerd.com/api/v1/checkins \
-H "Authorization: Bearer ck_live_…" \
-H "Content-Type: application/json" \
-d '{ "email": "[email protected]", "tag": "event" }'{
"result": "checked_in",
"data": {
"id": "a4c74c47-…",
"member": { "id": "1b39d6a5-…", "first_name": "Sam", "last_name": "Rivera" },
"kind": "event",
"tag": { "id": "ce415a9d-…", "label": "Event" },
"event": { "id": "c1f33a3b-…", "name": "Chapter Meeting" },
"at": "2026-11-05T23:04:11.000Z"
}
}Paths are relative to https://checkerd.com/api/v1. Each one needs the scope shown.
/meThe organization and the scopes this key has. Handy for testing a key.any key/orgName, timezone, check-in URL, tags (with their slugs), areas and sign-up questions.org:read/membersAll members, oldest first. Filter with q (name or email), email or phone.members:read/members/{id}One member with phone, email, sign-up answers and check-in total.members:read/membersAdd a member: first_name, last_name, phone or email, and answers. Same rules as sign-up.members:write/members/{id}Change any of those fields. Only what you send changes.members:write/members/{id}Delete a member and their check-in history.members:write/members/{id}/checkinsOne member's check-ins.checkins:read/checkinsEvery check-in, oldest first. Filter with since, until, member_id, event_id and kind (event or hangout).checkins:read/checkinsCheck a member in at a tag: member_id (or email or phone), tag (its slug) and, when two events are live, event_id.checkins:write/eventsEvents with check-in and RSVP counts. Filter with from and to.events:read/events/{id}One event.events:read/eventsAdd an event: name, start_at, end_at, and optionally area, venue, mode and rsvp_form_id.events:write/events/{id}Change it, force it on or off (mode), or make it RSVP-only (rsvp_form_id, null to turn off).events:write/events/{id}Delete an event. Its check-ins stay, with the event name.events:write/events/{id}/checkinsWho checked in to an event.checkins:read/events/{id}/rsvpsWho RSVP'd and when they checked in, if they did.rsvps:read/events/{id}/rsvpsPut someone on an RSVP-only event's list: first_name, last_name and the email or phone members sign in with (or member_id).rsvps:write/rsvp-formsYour RSVP forms, to use with rsvp_form_id.events:read/stats?period=monthThe dashboard's analytics for week, month, semester or year: check-ins, active and new members, first-timers, trends, busiest days and hours, top events.stats:read/leaderboardMembers ranked by check-ins. Filter with since, until, kind and limit (up to 100).stats:readCheckerd approves which scopes your organization can use. Owners then give each key only what it needs: a website that shows a leaderboard needs Analytics, nothing else.
Errors come back as { "error": { "code", "message" } } with a matching HTTP status.
Add an https endpoint in Settings → API and pick its events. Checkerd POSTs JSON to it within seconds, with the same shapes the API returns, and retries with backoff for about 8 hours until your endpoint answers 2xx. Use Checkerd-Delivery to ignore a delivery you've already handled.
checkin.createdSomeone checked in (a tap or the API).member.createdSomeone signed up, or a member was added through the API.member.updatedAn owner or the API changed a member's details.member.deletedA member was deleted.rsvp.createdSomeone RSVP'd to an event.event.createdAn event was added.event.updatedAn event was changed, or forced on or off.event.deletedAn event was deleted.Every delivery is signed with your endpoint's secret (shown once when you add it). Check the signature before you trust the body, and reject old timestamps. "Send test" in Settings delivers a ping.
POST /your-endpoint
Checkerd-Event: checkin.created
Checkerd-Delivery: 7f0e…
Checkerd-Signature: t=1793142251,v1=5d41402abc4b2a76…
{
"id": "7f0e…",
"type": "checkin.created",
"created_at": "2026-11-05T23:04:11.000Z",
"org": "your-org",
"data": { …same shape as the API… }
}Verify the signature (Node.js)import crypto from "node:crypto";
// rawBody: the request body exactly as received, before JSON.parse
export function verify(rawBody, header, secret) {
const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300; // 5 minutes
return fresh && crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}Webmaster, developer or officer, anyone can ask. Approval turns the API on for the organization, and one of its owners creates the keys. Not on Checkerd yet? Request a pilot first.