REST API
The Happa plugin API is installation-scoped. Every request uses the token for one installed user, and each endpoint enforces the scopes that installation was granted.
Base URL
https://us-central1-happa-1aff4.cloudfunctions.net/pluginApi
Authentication
Authorization: Bearer hpt_your_installation_token
Missing or invalid tokens return 401. Valid tokens without the right scope return 403.
Rate limits
| Window | Limit |
|---|---|
| Hourly | 600 requests per installation token |
| Daily | 5000 requests per installation token |
When the limit is exceeded, the API responds with 429 and includes Retry-After.
Events
Requires events.read unless noted otherwise.
GET /events
Lists events owned by the installing organizer. Supports limit and cursor.
curl "https://us-central1-happa-1aff4.cloudfunctions.net/pluginApi/events?limit=20" \
-H "Authorization: Bearer hpt_..."
GET /events/:id
Returns one event. Access is limited to organizer-owned events.
PATCH /events/:id
Requires events.write. You can update only description, location, and eventDate.
curl -X PATCH "https://us-central1-happa-1aff4.cloudfunctions.net/pluginApi/events/abc123" \
-H "Authorization: Bearer hpt_..." \
-H "Content-Type: application/json" \
-d '{
"description": "Doors open at 7PM",
"location": "123 Main St, Austin TX",
"eventDate": "2026-08-15T18:00:00.000Z"
}'
Attendees
GET /events/:id/attendees
Requires attendees.read. Returns attendee IDs plus display names and photo URLs when available.
POST /events/:id/attendees
Requires attendees.write. Adds one attendee by user ID.
curl -X POST "https://us-central1-happa-1aff4.cloudfunctions.net/pluginApi/events/abc123/attendees" \
-H "Authorization: Bearer hpt_..." \
-H "Content-Type: application/json" \
-d '{ "userId": "user_456" }'
DELETE /events/:id/attendees/:uid
Requires attendees.write. Removes one attendee by user ID.
GET /attendees?eventId=:id
Alias that redirects to the canonical attendees endpoint.
Comments
GET /events/:id/comments
Requires events.read. Supports limit and cursor, returns newest comments first, and allows public-event reads even when the event is not owned by the installer.
Polls
Poll endpoints are available when the installation has events.read. The backend also honors legacy polls.read tokens if they already exist.
GET /events/:id/polls
Lists polls for an organizer-owned event, including live nominee vote counts.
GET /events/:id/polls/:pollId
Returns one poll object with status, resultsVisibility, nominee metadata, and totalVotes.
Tickets
GET /events/:id/revenue
Requires tickets.read. Returns aggregate ticketsSold, totalRevenue, and currency for an organizer-owned event. Buyer PII is not exposed through this endpoint.
Profile
GET /profile
Requires profile.read. Returns the installing user's profile and follower/following counts.
{
"uid": "user456",
"displayName": "Jane Smith",
"photoUrl": "https://...",
"followerCount": 340,
"followingCount": 88,
"pluginId": "plg_123"
}
Pagination shape
{
"events": [/* ... */],
"nextCursor": "abc123",
"hasMore": true
}
Error responses
{ "error": "Scope attendees.read not granted" }
See the Error Codes reference for the full response matrix and the most common causes.
Implementation tip: use webhooks to know when to fetch and the REST API to fetch the fresh state you need. That pattern keeps your token usage low and your plugin responsive.