01

Overview

The Eventloop API is a REST API that returns JSON. Every event is an endpoint. Query data, register attendees, and sync with your own tooling.

Format

JSON

Auth

Bearer JWT

Version

v1

terminal — quick_start.sh
# List all events
curl https://api.eventloop.to/v1/events

# Get a single event
curl https://api.eventloop.to/v1/events/evt_abc123

# Create an event (auth required)
curl -X POST https://api.eventloop.to/v1/events \
  -H "Authorization: Bearer <your_token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"My Hackathon", ...}'

02

Authentication

Read endpoints are public. Write endpoints (POST, PATCH) require authentication via a Bearer token. There are two token types:

Clerk JWT

Web / Server

Short-lived session token from the Clerk SDK. Use this in web apps and Next.js server components. Expires with the session.

API Key

CLI / Scripts

Long-lived eventloop_key_ prefixed token. Generate one from your dashboard. Scoped to specific permissions. Does not expire automatically.

Clerk JWT — from a Next.js app

lib/api.ts
import { auth } from "@clerk/nextjs/server"

async function createEvent(data: CreateEventInput) {
  const { getToken } = await auth()
  const token = await getToken()

  const res = await fetch("https://api.eventloop.to/v1/events", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(data),
  })

  return res.json()
}

API Key — from a CLI or script

terminal — auth.sh
# Set your API key (generate one at eventloop.to/dashboard)
export EVENTLOOP_KEY="eventloop_key_..."

# Use it exactly like a Bearer token
curl https://api.eventloop.to/v1/me/events \
  -H "Authorization: Bearer $EVENTLOOP_KEY"

# Write operations require events:write scope (Pro)
curl -X POST https://api.eventloop.to/v1/events \
  -H "Authorization: Bearer $EVENTLOOP_KEY" \
  -H "Content-Type: application/json" \
  -d @event.json

API keys are shown once on creation and cannot be retrieved again. Store them securely (e.g. in environment variables or a secrets manager). If a key is compromised, revoke it from your dashboard immediately.

03

API Keys

API keys let you authenticate from any HTTP client — CLIs, scripts, CI pipelines, or third-party apps — without a browser session. Keys are scoped to specific permissions and can be revoked at any time from your dashboard.

Scopes

Each key is granted one or more scopes at creation time. Clerk JWT sessions (web app users) are not scope-restricted.

events:readFreeList and retrieve events.
events:writeProCreate, update, and claim events.
registrations:readProRead registrations for events you own.
registrations:writeProCreate and manage registrations.

Managing keys via the API

GEThttps://api.eventloop.to/v1/me/api-keys🔒 Auth required

Lists all API keys for the authenticated user. Tokens are never returned after creation.

Response

{
  "data": [
    {
      "id": "key_abc123",
      "name": "my-cli",
      "scopes": ["events:read"],
      "lastUsedAt": "2026-03-10T09:00:00.000Z",
      "createdAt": "2026-03-01T12:00:00.000Z"
    }
  ]
}
POSThttps://api.eventloop.to/v1/me/api-keys🔒 Auth required

Creates a new API key. The raw token is returned once in this response and never again. Pro plan required for write scopes.

Request body

{
  "name": "my-cli",
  "scopes": ["events:read"]
}

Response

{
  "data": {
    "id": "key_abc123",
    "name": "my-cli",
    "scopes": ["events:read"],
    "token": "eventloop_key_...",
    "lastUsedAt": null,
    "createdAt": "2026-03-10T12:00:00.000Z"
  }
}
DELETEhttps://api.eventloop.to/v1/me/api-keys/:id🔒 Auth required

Revokes an API key immediately. Any in-flight requests using the key will fail.

Parameters

idstringThe key_ prefixed API key ID

Response

{ "success": true }
GEThttps://api.eventloop.to/v1/me/plan🔒 Auth required

Returns the current user's plan. Used to determine which scopes are available.

Response

{
  "data": {
    "plan": "free"
  }
}
GEThttps://api.eventloop.to/v1/me/events🔒 Auth required

Returns all events claimed by the authenticated user, ordered by start date.

Response

{
  "data": [
    {
      "id": "evt_88abc123",
      "name": "Global AI Hack",
      "status": "published",
      "claimed": true,
      "isOwner": true,
      ...
    }
  ]
}

04

Events

Events are the core resource. Each event has a unique evt_ prefixed ID.

GEThttps://api.eventloop.to/v1/events

Returns events visible to the caller, ordered by start date. Draft events are only returned to their owner. Supports optional query parameters to filter results.

Parameters

locationstringCase-insensitive partial match on the location field.
fromdateReturn events with a start date on or after this ISO date.
todateReturn events with a start date on or before this ISO date.
statusenumFilter by status: published · draft · cancelled · completed.

Response

{
  "data": [
    {
      "id": "evt_88abc123",
      "name": "Global AI Hack",
      "status": "published",
      "location": "London, UK",
      "startDate": "2026-06-01T09:00:00.000Z",
      "endDate": "2026-06-02T18:00:00.000Z",
      "capacity": 200,
      "organizerId": "org_xyz456",
      "organizerName": "Hack Club London",
      "claimable": true,
      "claimed": false,
      "isOwner": false,
      "createdAt": "2026-03-01T12:00:00.000Z",
      "updatedAt": "2026-03-01T12:00:00.000Z"
    }
  ]
}
GEThttps://api.eventloop.to/v1/events/:id

Returns a single event by its ID. Draft events return 404 to non-owners. Authenticated callers get isOwner: true if they claimed the event.

Parameters

idstringThe evt_ prefixed event ID

Response

{
  "data": {
    "id": "evt_88abc123",
    "name": "Global AI Hack",
    "status": "published",
    "description": "48 hours. Build something wild.",
    "location": "London, UK",
    "startDate": "2026-06-01T09:00:00.000Z",
    "endDate": "2026-06-02T18:00:00.000Z",
    "capacity": 200,
    "organizerId": "org_xyz456",
    "organizerName": "Hack Club London",
    "claimable": true,
    "claimed": false,
    "isOwner": false,
    "createdAt": "2026-03-01T12:00:00.000Z",
    "updatedAt": "2026-03-01T12:00:00.000Z"
  }
}
POSThttps://api.eventloop.to/v1/events/:id/claim🔒 Auth required

Claims an unclaimed claimable event, associating it with the authenticated user. Requires events:write scope (Pro plan).

Parameters

idstringThe evt_ prefixed event ID

Response

{
  "data": {
    "id": "evt_88abc123",
    "name": "Global AI Hack",
    "claimed": true,
    "isOwner": true,
    ...
  }
}
POSThttps://api.eventloop.to/v1/events🔒 Auth required

Creates a new event. Requires events:write scope (Pro plan).

Request body

{
  "name": "Global AI Hack",
  "description": "48 hours. Build something wild.",
  "status": "draft",
  "location": "London, UK",
  "startDate": "2026-06-01T09:00:00.000Z",
  "endDate": "2026-06-02T18:00:00.000Z",
  "capacity": 200,
  "organizerId": "org_xyz456"
}

Response

{
  "data": {
    "id": "evt_88abc123",
    "name": "Global AI Hack",
    "status": "draft",
    ...
  }
}
PATCHhttps://api.eventloop.to/v1/events/:id🔒 Auth required

Partially updates an event. Only include the fields you want to change. Only the user who claimed the event can update it. Requires events:write scope (Pro plan).

Parameters

idstringThe evt_ prefixed event ID

Request body

{
  "status": "published",
  "capacity": 250
}

Response

{
  "data": {
    "id": "evt_88abc123",
    "status": "published",
    "capacity": 250,
    ...
  }
}

05

Organizers

Organizers own events. Each organizer has a unique org_ prefixed ID.

GEThttps://api.eventloop.to/v1/organizers

Returns all organizers.

Response

{
  "data": [
    {
      "id": "org_xyz456",
      "name": "Hack Club London",
      "slug": "hack-club-london",
      "createdAt": "2026-01-01T00:00:00.000Z"
    }
  ]
}
GEThttps://api.eventloop.to/v1/organizers/:id

Returns a single organizer by their ID.

Parameters

idstringThe org_ prefixed organizer ID

Response

{
  "data": {
    "id": "org_xyz456",
    "name": "Hack Club London",
    "slug": "hack-club-london",
    "website": "https://hackclub.london",
    "createdAt": "2026-01-01T00:00:00.000Z"
  }
}
GEThttps://api.eventloop.to/v1/organizers/:id/events

Returns all publicly visible events for the given organizer.

Parameters

idstringThe org_ prefixed organizer ID

Response

{
  "data": [
    {
      "id": "evt_88abc123",
      "name": "Global AI Hack",
      "status": "published",
      ...
    }
  ]
}
POSThttps://api.eventloop.to/v1/organizers🔒 Auth required

Creates a new organizer profile.

Request body

{
  "name": "Hack Club London",
  "slug": "hack-club-london",
  "website": "https://hackclub.london"
}

Response

{
  "data": {
    "id": "org_xyz456",
    "name": "Hack Club London",
    "slug": "hack-club-london",
    "website": "https://hackclub.london",
    "createdAt": "2026-03-09T12:00:00.000Z"
  }
}

06

Error Codes

All errors return a JSON body with an error field describing the problem.

400

Bad Request

The request body failed validation. Check the required fields.

401

Unauthorized

Missing or invalid Bearer token. Sign in and retry with a fresh token.

403

Forbidden

Valid token but insufficient permissions. API keys may lack the required scope, or a Pro plan is needed.

404

Not Found

The requested resource does not exist. Check the ID.

500

Server Error

Something went wrong on our end. Check status.eventloop.to.

// All error responses follow this shape:
{
  "error": "Unauthorized"
}

© 2026 EVENTLOOP

API_Online