sheeets API
A RESTful API for browsing crypto conference side events, managing itineraries, and building AI agent integrations. All event data is public. Authenticated endpoints let agents act on behalf of users.
Quick Start
The event endpoints are public and require no authentication. Try it now:
curl "https://qsiukfwuwbpwyujfahtz.supabase.co/functions/v1/agent-api/events?search=pizza&free=true"For authenticated endpoints (itinerary, friends, RSVPs), you need an API key.
Authentication
The API uses two authentication methods depending on the endpoint:
For most authenticated endpoints. Create an API key from the sheeets app or via the key management endpoints.
Authorization: Bearer shts_a1b2c3d4...For API key management only. Use a Supabase session JWT from the web app.
Authorization: Bearer eyJhbGciOi...How API Key Auth Works
- API keys have the format
shts_+ 32 hex characters - Send the key in the
Authorization: Bearerheader - The server SHA-256 hashes the key and looks up the user and scopes
- A short-lived JWT is minted for the resolved user — all Supabase RLS policies apply automatically
curl "https://qsiukfwuwbpwyujfahtz.supabase.co/functions/v1/agent-api/itinerary" \
-H "Authorization: Bearer shts_your_api_key_here"Base URL
https://qsiukfwuwbpwyujfahtz.supabase.co/functions/v1/agent-apiAll endpoint paths below are relative to this base URL.
Endpoints
Events
All event endpoints are public and require no authentication.
/eventsPublicSearch and filter events. Returns paginated results.
Query Parameters
| Param | Type | Description |
|---|---|---|
conference | string | Filter by conference name (e.g. "ETH Denver 2026") |
date | string | Filter by date (ISO format: 2026-02-16) |
tags | string | Comma-separated tag filter (e.g. "AI,DeFi") |
search | string | Full-text search across name, organizer, address, tags |
free | boolean | Filter to free events only (free=true) |
now | boolean | Show events happening now or starting within 1 hour |
Response
{
"events": [
{
"id": "evt-ethdenver-42",
"name": "Pizza Party",
"organizer": "PizzaDAO",
"date": "Feb 16",
"dateISO": "2026-02-16",
"startTime": "6:00 PM",
"endTime": "9:00 PM",
"address": "123 Main St, Denver",
"cost": "Free",
"isFree": true,
"tags": ["Party", "Food"],
"conference": "ETH Denver 2026",
"link": "https://lu.ma/pizza-party"
}
],
"total": 228
}/events/:idPublicGet a single event by ID.
Response
{
"event": {
"id": "evt-ethdenver-42",
"name": "Pizza Party",
...
}
}/events/conferencesPublicList all available conferences.
Response
{
"conferences": [
"ETH Denver 2026",
"Consensus Hong Kong 2026"
]
}/events/tagsPublicList all available tags with their event counts.
Response
{
"tags": [
{ "tag": "AI", "count": 45 },
{ "tag": "DeFi", "count": 32 },
...
]
}/events/datesPublicList all dates that have events.
Response
{
"dates": [
"2026-02-10",
"2026-02-11",
...
]
}Itinerary
Manage the authenticated user's starred/saved events.
/itineraryAPI Keyitinerary:readGet the user's saved events with full event data.
Response
{
"events": [
{
"id": "evt-ethdenver-42",
"name": "Pizza Party",
"date": "Feb 16",
"startTime": "6:00 PM",
...
}
],
"total": 5
}/itinerary/addAPI Keyitinerary:writeAdd events to the user's itinerary. Duplicate IDs are silently ignored.
Request Body
{
"eventIds": ["evt-ethdenver-42", "evt-ethdenver-99"]
}Response
{
"added": 2,
"total": 7
}/itinerary/removeAPI Keyitinerary:writeRemove events from the user's itinerary.
Request Body
{
"eventIds": ["evt-ethdenver-42"]
}Response
{
"removed": 1,
"total": 6
}/itineraryAPI Keyitinerary:writeClear all events from the user's itinerary.
Response
{
"cleared": true
}/itinerary/conflictsAPI Keyitinerary:readDetect scheduling conflicts among saved events. Uses 2-hour default duration for events without end times.
Response
{
"conflicts": [
{
"event_a": "evt-ethdenver-42",
"event_b": "evt-ethdenver-99",
"overlap_minutes": 60
}
]
}/itinerary/shareAPI Keyitinerary:readCreate a shareable link for the current itinerary. Returns an 8-character short code.
Response
{
"url": "https://sheeets.vercel.app/itinerary/s/abc12345",
"code": "abc12345"
}/itinerary/exportAPI Keyitinerary:readExport the itinerary as JSON. ICS (calendar) format is also supported.
Query Parameters
| Param | Type | Description |
|---|---|---|
format | string | "json" (default) or "ics" |
Response
{
"events": [...],
"exported_at": "2026-02-16T14:30:00Z"
}Friends
Read-only access to the authenticated user's friends list.
/friendsAPI Keyfriends:readList the user's friends with their profile information.
Response
{
"friends": [
{
"user_id": "uuid-123",
"display_name": "Alice",
"x_handle": "@alice_eth"
}
]
}/friends/goingAPI Keyfriends:readSee which friends are going to a specific event (or all events if no eventId specified).
Query Parameters
| Param | Type | Description |
|---|---|---|
eventId | string | Filter to a specific event ID |
Response
{
"friends_going": [
{
"user_id": "uuid-123",
"display_name": "Alice",
"event_ids": ["evt-ethdenver-42"]
}
]
}RSVPs
Manage RSVPs for Luma-powered events.
/rsvpsAPI Keyrsvps:readList all RSVPs for the authenticated user.
Response
{
"rsvps": [
{
"event_id": "evt-ethdenver-42",
"status": "confirmed",
"method": "api",
"created_at": "2026-02-15T10:00:00Z"
}
]
}/rsvpsAPI Keyrsvps:writeRSVP to an event. Creates a record in the rsvps table.
Request Body
{
"eventId": "evt-ethdenver-42"
}Response
{
"rsvp": {
"event_id": "evt-ethdenver-42",
"status": "confirmed"
}
}Recommendations
Get personalized event suggestions based on the user's itinerary tags and friends' attendance.
/recommendationsAPI Keyrecommendations:readGet personalized event recommendations. Scoring uses tag frequency from the user's itinerary plus a social signal (3 points per friend attending).
Response
{
"recommendations": [
{
"event": {
"id": "evt-ethdenver-55",
"name": "DeFi Builder Night",
...
},
"score": 12.5,
"reasons": ["Matches your tags: DeFi, Networking", "2 friends going"]
}
]
}API Key Management
Create and manage API keys. These endpoints require JWT authentication (Supabase session token), not API key auth.
/keysJWTCreate a new API key. The raw key is only returned once — store it securely.
Request Body
{
"scopes": [
"events:read",
"itinerary:read",
"itinerary:write",
"friends:read"
],
"name": "My Claude Agent"
}Response
{
"key": "shts_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"id": "uuid-key-123",
"scopes": ["events:read", "itinerary:read", "itinerary:write", "friends:read"],
"name": "My Claude Agent",
"created_at": "2026-02-16T14:30:00Z"
}/keysJWTList all API keys for the authenticated user. The raw key is never returned — only the prefix and metadata.
Response
{
"keys": [
{
"id": "uuid-key-123",
"key_prefix": "shts_a1b2",
"scopes": ["events:read", "itinerary:read"],
"name": "My Claude Agent",
"created_at": "2026-02-16T14:30:00Z",
"last_used_at": "2026-02-16T15:00:00Z"
}
]
}/keys/:idJWTRevoke (delete) an API key. This is irreversible.
Response
{
"revoked": true
}Scopes
API keys are scoped to limit access. Assign only the scopes your agent needs.
| Scope | Grants Access To |
|---|---|
events:read | Search and filter events, list conferences/tags/dates (also public) |
itinerary:read | View saved events, detect conflicts, share, export |
itinerary:write | Add/remove events from itinerary, clear all |
friends:read | List friends, see which friends are attending events |
rsvps:read | List RSVPs |
rsvps:write | RSVP to events |
recommendations:read | Get personalized event recommendations |
Rate Limits
60
requests per minute
Per Key
rate limit scope
Atomic
Postgres counter (no race conditions)
When rate limited, the API returns 429 Too Many Requests with a Retry-After header indicating seconds to wait.
HTTP/1.1 429 Too Many Requests
Retry-After: 45
Content-Type: application/json
{
"error": "Rate limit exceeded",
"retry_after": 45
}Public endpoints (events) are not rate limited per key but are subject to Supabase Edge Function concurrency limits.
Response Format
All responses are JSON. Successful responses return the requested data directly. Errors follow a consistent format:
Success (200)
{
"events": [...],
"total": 42
}Error (4xx / 5xx)
{
"error": "Invalid API key",
"status": 401
}Common HTTP status codes:
| Code | Meaning |
|---|---|
200 | Success |
400 | Bad request (missing or invalid parameters) |
401 | Unauthorized (missing or invalid auth) |
403 | Forbidden (insufficient scopes) |
404 | Not found |
429 | Rate limited |
500 | Internal server error |
MCP Server
The sheeets MCP server wraps this REST API as Model Context Protocol tools, so AI assistants like Claude can interact with sheeets natively.
Installation
npm install @sheeets/mcp-serverConfiguration
Add the server to your MCP client config (e.g. Claude Desktop):
{
"mcpServers": {
"sheeets": {
"command": "npx",
"args": ["@sheeets/mcp-server"],
"env": {
"SHEEETS_API_KEY": "shts_your_api_key_here"
}
}
}
}Available Tools
The MCP server exposes the following tools to AI assistants:
| Tool | Description |
|---|---|
search_events | Search and filter events |
get_event | Get a single event by ID |
list_conferences | List available conferences |
list_tags | List available tags |
list_dates | List event dates |
get_itinerary | Get saved events |
add_to_itinerary | Add events to itinerary |
remove_from_itinerary | Remove events from itinerary |
clear_itinerary | Clear all saved events |
get_conflicts | Detect scheduling conflicts |
share_itinerary | Create a shareable link |
export_itinerary | Export itinerary as JSON or ICS |
list_friends | List friends |
friends_going | See which friends attend an event |
list_rsvps | List RSVPs |
rsvp_to_event | RSVP to an event |
get_recommendations | Get personalized suggestions |
Built by sheeets.xyz
API version 0.4.0