API
JSON API for third-party builders
Base path: /api/v1 · JSON only · Bearer tokens for capability links.
Authentication
- Event owner token (admin token) → required for editing/deleting events or listing/deleting RSVPs:
Authorization: Bearer <event-owner-token>. - RSVP token → required for managing your own RSVP at
/events/{event_id}/rsvps/self. - No root-level API; root admin stays CLI-only.
Note: the root admin token can stand in anywhere an event owner token is required.
timezone_offset_minutes when creating/updating events so local times are stored correctly in UTC.
Private RSVPs are hidden from GET /api/v1/events/{id} but are visible when using the event owner endpoints.
Public responses omit private channel metadata and redact locations for approval-required events unless you send an admin/root token or an approved Yes RSVP token.
Key endpoints
?q=.Create an event
Send ISO8601 times. Pass timezone_offset_minutes (e.g., browser timezone offset) so local times normalize to UTC.
curl -X POST http://localhost:8000/api/v1/events \
-H "Content-Type: application/json" \
-d '{
"title": "Cedar Social: Cigar Night",
"description": "Monthly hang at the lounge.",
"start_time": "2024-08-22T19:00:00",
"end_time": "2024-08-22T21:30:00",
"timezone_offset_minutes": -300,
"location": "Cedar Social, Austin",
"channel_name": "ATX Cigars",
"channel_visibility": "public",
"is_private": false
}'
admin_token (the event owner token) plus links.admin for the owner page and links.public for the guest view.
Create an RSVP
No auth required to submit; the response includes the RSVP token.
curl -X POST http://localhost:8000/api/v1/events/{event_id}/rsvps \
-H "Content-Type: application/json" \
-d '{
"name": "Sky",
"status": "yes",
"pronouns": "they/them",
"guest_count": 1,
"notes": "Can bring a projector",
"is_private_rsvp": false
}'
Guests manage their own entry at /api/v1/events/{event_id}/rsvps/self using Authorization: Bearer <rsvp-token>. Responses include approval_status (approved/pending/rejected).
curl -X PATCH http://localhost:8000/api/v1/events/{event_id}/rsvps/self \
-H "Authorization: Bearer <rsvp-token>" \
-H "Content-Type: application/json" \
-d '{"status": "no", "notes": "Out of town"}'
List public events
Returns only public (non-private) events with pagination. per_page is capped to prevent huge responses.
curl "http://localhost:8000/api/v1/events?page=1&per_page=10"
Private events never appear in this listing; they remain reachable only via their exact IDs or the root admin UI. Approval-required events return location: null until an approved Yes token (or admin/root token) is supplied, and counts only include approved RSVPs.
Filter by date range
Use ISO8601 timestamps to bound start times. Both parameters are optional.
curl "http://localhost:8000/api/v1/events?start_after=2024-08-01T00:00:00&start_before=2024-08-31T23:59:59"
start_before must be after start_after. The response echoes pagination and the applied filters.
Event owner actions on events
Use the event owner token (admin token) as a bearer to edit or delete.
Third-party apps can delete events the same way the owner UI does by calling the DELETE endpoint with the event owner token.
curl -X PATCH http://localhost:8000/api/v1/events/{event_id} \
-H "Authorization: Bearer <event-owner-token>" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated title",
"channel_name": "Private Circle",
"channel_visibility": "private",
"is_private": true
}'
Deleting an event (DELETE /api/v1/events/{id}) removes the event and all RSVPs. This is irreversible.
List RSVPs with stats (event owner)
Returns RSVP records (including private ones) plus convenience counts.
curl http://localhost:8000/api/v1/events/{event_id}/rsvps \
-H "Authorization: Bearer <event-owner-token>"
Events with approval enabled include approval_status on each RSVP; pending/rejected entries stay off the public attendee list.
Example stats payload:
{
"stats": {
"yes_count": 6,
"yes_guest_count": 3,
"yes_total": 9,
"maybe_count": 2,
"no_count": 1
}
}
Event owners can delete specific RSVPs via DELETE /api/v1/events/{event_id}/rsvps/{rsvp_token}.
Approve or reject pending RSVPs
When Require admin approval is enabled, new RSVPs enter the pending queue until an event owner (or root admin token) sends one of the approval endpoints below.
POST /api/v1/events/{event_id}/rsvps/{rsvp_id}/approve— marks the RSVP approved and adds an owner-visible log entry.POST /api/v1/events/{event_id}/rsvps/{rsvp_id}/reject— accepts optional JSON body{"reason": "Capacity reached"}that is shared with the attendee.POST /api/v1/events/{event_id}/rsvps/{rsvp_id}/pending— moves the RSVP back into the pending state.
All three routes require Authorization: Bearer <event-owner-token> or the root admin token from docker exec openrsvp openrsvp admin-token. Responses return the updated RSVP plus its attendee-facing messages.
curl -X POST http://localhost:8000/api/v1/events/{event_id}/rsvps/{rsvp_id}/approve \
-H "Authorization: Bearer <event-owner-token>"
Messages API
Send announcements or direct messages between hosts and attendees.
POST /api/v1/events/{event_id}/messages— event announcements (visibility: public or admin).POST /api/v1/events/{event_id}/rsvps/{rsvp_id}/messages— admin notes or direct messages to a guest.POST /api/v1/events/{event_id}/rsvps/self/messages— attendee message to the organizer.
curl -X POST http://localhost:8000/api/v1/events/{event_id}/messages \
-H "Authorization: Bearer <event-owner-token>" \
-H "Content-Type: application/json" \
-d '{"content": "Doors open 15 minutes early.", "visibility": "public", "message_type": "event_update"}'
Event detail responses include public announcements in messages; RSVP detail responses include attendee-visible messages.