sheeets.xyzAPI v0.4.0

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:

API Key

For most authenticated endpoints. Create an API key from the sheeets app or via the key management endpoints.

Authorization: Bearer shts_a1b2c3d4...
JWT

For API key management only. Use a Supabase session JWT from the web app.

Authorization: Bearer eyJhbGciOi...

How API Key Auth Works

  1. API keys have the format shts_ + 32 hex characters
  2. Send the key in the Authorization: Bearer header
  3. The server SHA-256 hashes the key and looks up the user and scopes
  4. 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-api

All endpoint paths below are relative to this base URL.

Endpoints

Events

All event endpoints are public and require no authentication.

GET/eventsPublic

Search and filter events. Returns paginated results.

Query Parameters

ParamTypeDescription
conferencestringFilter by conference name (e.g. "ETH Denver 2026")
datestringFilter by date (ISO format: 2026-02-16)
tagsstringComma-separated tag filter (e.g. "AI,DeFi")
searchstringFull-text search across name, organizer, address, tags
freebooleanFilter to free events only (free=true)
nowbooleanShow 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
}
GET/events/:idPublic

Get a single event by ID.

Response

{
  "event": {
    "id": "evt-ethdenver-42",
    "name": "Pizza Party",
    ...
  }
}
GET/events/conferencesPublic

List all available conferences.

Response

{
  "conferences": [
    "ETH Denver 2026",
    "Consensus Hong Kong 2026"
  ]
}
GET/events/tagsPublic

List all available tags with their event counts.

Response

{
  "tags": [
    { "tag": "AI", "count": 45 },
    { "tag": "DeFi", "count": 32 },
    ...
  ]
}
GET/events/datesPublic

List all dates that have events.

Response

{
  "dates": [
    "2026-02-10",
    "2026-02-11",
    ...
  ]
}

Itinerary

Manage the authenticated user's starred/saved events.

GET/itineraryAPI Keyitinerary:read

Get 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
}
POST/itinerary/addAPI Keyitinerary:write

Add 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
}
POST/itinerary/removeAPI Keyitinerary:write

Remove events from the user's itinerary.

Request Body

{
  "eventIds": ["evt-ethdenver-42"]
}

Response

{
  "removed": 1,
  "total": 6
}
DELETE/itineraryAPI Keyitinerary:write

Clear all events from the user's itinerary.

Response

{
  "cleared": true
}
GET/itinerary/conflictsAPI Keyitinerary:read

Detect 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
    }
  ]
}
POST/itinerary/shareAPI Keyitinerary:read

Create a shareable link for the current itinerary. Returns an 8-character short code.

Response

{
  "url": "https://sheeets.vercel.app/itinerary/s/abc12345",
  "code": "abc12345"
}
GET/itinerary/exportAPI Keyitinerary:read

Export the itinerary as JSON. ICS (calendar) format is also supported.

Query Parameters

ParamTypeDescription
formatstring"json" (default) or "ics"

Response

{
  "events": [...],
  "exported_at": "2026-02-16T14:30:00Z"
}

Friends

Read-only access to the authenticated user's friends list.

GET/friendsAPI Keyfriends:read

List the user's friends with their profile information.

Response

{
  "friends": [
    {
      "user_id": "uuid-123",
      "display_name": "Alice",
      "x_handle": "@alice_eth"
    }
  ]
}
GET/friends/goingAPI Keyfriends:read

See which friends are going to a specific event (or all events if no eventId specified).

Query Parameters

ParamTypeDescription
eventIdstringFilter 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.

GET/rsvpsAPI Keyrsvps:read

List all RSVPs for the authenticated user.

Response

{
  "rsvps": [
    {
      "event_id": "evt-ethdenver-42",
      "status": "confirmed",
      "method": "api",
      "created_at": "2026-02-15T10:00:00Z"
    }
  ]
}
POST/rsvpsAPI Keyrsvps:write

RSVP 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.

GET/recommendationsAPI Keyrecommendations:read

Get 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.

POST/keysJWT

Create 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"
}
GET/keysJWT

List 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"
    }
  ]
}
DELETE/keys/:idJWT

Revoke (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.

ScopeGrants Access To
events:readSearch and filter events, list conferences/tags/dates (also public)
itinerary:readView saved events, detect conflicts, share, export
itinerary:writeAdd/remove events from itinerary, clear all
friends:readList friends, see which friends are attending events
rsvps:readList RSVPs
rsvps:writeRSVP to events
recommendations:readGet 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:

CodeMeaning
200Success
400Bad request (missing or invalid parameters)
401Unauthorized (missing or invalid auth)
403Forbidden (insufficient scopes)
404Not found
429Rate limited
500Internal 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-server

Configuration

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:

ToolDescription
search_eventsSearch and filter events
get_eventGet a single event by ID
list_conferencesList available conferences
list_tagsList available tags
list_datesList event dates
get_itineraryGet saved events
add_to_itineraryAdd events to itinerary
remove_from_itineraryRemove events from itinerary
clear_itineraryClear all saved events
get_conflictsDetect scheduling conflicts
share_itineraryCreate a shareable link
export_itineraryExport itinerary as JSON or ICS
list_friendsList friends
friends_goingSee which friends attend an event
list_rsvpsList RSVPs
rsvp_to_eventRSVP to an event
get_recommendationsGet personalized suggestions

Built by sheeets.xyz

API version 0.4.0