An activity is an event with a capacity and a check-in window. Sessions are timeslots within it. Attendees check in by presenting an identifier (a card tap, QR scan, wallet, or username), which writes an immutable proof and can feed reward triggers.
All paths are under https://api.davi.social/api/v1; managing an org's activities
uses an org-scoped token.
Create an activity and sessions
curl -X POST \
"https://api.davi.social/api/v1/organizations/ORG_SLUG/activities" \
-H "Authorization: Bearer ORG_SCOPED_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Launch Night",
"description": "Doors at 7pm",
"max_attendees": 200,
"start_time": "2026-02-01T19:00:00Z",
"end_time": "2026-02-01T23:00:00Z",
"requires_ticket": false
}'
Key fields: max_attendees (null = unlimited), start_time / end_time (the
check-in window), and requires_ticket + ticket_template_uuid to gate entry.
Add timeslots with POST /activities/{activity_slug}/sessions (each session can
override capacity and ticketing, or inherit from the activity).
| Method | Path | Scope |
|---|---|---|
| POST | /organizations/{organization_slug}/activities | activity:create |
| GET | /activities/{activity_slug} | activity:read |
| POST | /activities/{activity_slug}/sessions | activity:create |
| GET | /activities/{activity_slug}/attendees | activity:attendees:read |
Tickets and registration
There is no separate "register" call — registration means holding a valid
ticket. When an activity or session sets requires_ticket, an attendee must
already hold the ticket, which is a reward issued from the
ticket_template_uuid. Open events (requires_ticket: false) let anyone check
in.
Check in
Check a person into a session with POST /sessions/{session_slug}/attend
(scope activity:attend):
curl -X POST \
"https://api.davi.social/api/v1/sessions/SESSION_SLUG/attend" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"identifier": { "type": "card", "value": "CARD_IDENTIFIER" },
"idempotency_key": "unique-per-checkin",
"proof_metadata": { "method": "nfc_tap" }
}'
identifieris anIdentifierRef—typeiscard,wallet,username,user_id, orlink.proof_metadatais optional context (e.g.methodnfc_tap/qr_scan, location, device).- Checking in yourself (the resolved identity matches your token) is
self-service; checking in others (a kiosk or door app) needs
activity:attendees:manageand an org-scoped token.
The response includes status, action_taken, the on-chain
attendance_proof_tx_id, and the resolved ticket / user. A kiosk can call
GET /sessions/{session_slug}/eligibility first to decide the recommended action.
Check-ins are de-duplicated server-side per session and attendee, so a repeated
tap won't double-record. If a request fails with no response, re-read the
attendee's status rather than repeating the write —
GET /sessions/{session_slug}/attendee-status tells you whether it landed.
What check-ins power
Each check-in writes an immutable proof and emits an activity.checked_in
event — which drives reward triggers (e.g.
activity.checked_in:count:5), the user's feed,
and webhooks.
Next
- Rewards & triggers — reward attendance automatically.