Skip to main content

API Reference

Programmatically manage schedules and events with the Event Schedule REST API. Write operations require a Pro plan. A machine-readable OpenAPI spec is also available.

Authentication

Most API endpoints require authentication via an API key in the X-API-Key header. You can get an API key by:

API Key Security

Keep your API key secure and never expose it in client-side code. API keys expire after 1 year. Login generates a new key each time, replacing any existing key.

cURL Example
curl -X GET "https://eventschedule.com/api/schedules" \
     -H "X-API-Key: your_api_key_here"

Rate Limits

API requests are rate limited per IP address:

Operation TypeLimitHTTP Methods
Read operations300 requests/minuteGET
Write operations30 requests/minutePOST, PUT, DELETE

Auth endpoints (register, login) have separate per-endpoint rate limits. When rate limited, the API returns a 429 status code.

Rate Limit Response (429)
{
    "error": "Rate limit exceeded"
}

Response Format

Successful responses wrap results in a data property. List endpoints include a meta object with pagination. Error responses use an error property.

Success Response
{
    "data": [...],
    "meta": {
        "current_page": 1,
        "total": 50
    }
}
Error Response
{
    "error": "Validation failed",
    "errors": {
        "name": ["The name field is required."]
    }
}

Pagination

List endpoints support pagination through query parameters:

ParameterDefaultDescription
page1Page number to retrieve
per_page100Number of items per page (max: 500)
cURL
curl -X GET "https://eventschedule.com/api/events?page=2&per_page=50" \
     -H "X-API-Key: your_api_key_here"

Register

Registration is a two-step process: first send a verification code, then register with it.

Step 1: Send Verification Code

POST /api/register/send-code

No authentication required. Rate limited to 5 codes per email per hour.

Step 2: Register

POST /api/register

No authentication required. Rate limited to 3 registrations per IP per hour.

ParameterRequiredDescription
nameYesYour display name
emailYesEmail address
passwordYesPassword (min 8 characters)
verification_codeYes6-digit code from Step 1
timezoneNoTimezone (default: America/New_York)
language_codeNoLanguage code (default: en)
Step 1: Send Code
curl -X POST "https://eventschedule.com/api/register/send-code" \
     -H "Content-Type: application/json" \
     -d '{"email": "[email protected]"}'
Response (201)
{
    "data": {
        "api_key": "your_new_api_key",
        "api_key_expires_at": "2027-02-28T00:00:00Z",
        "user": {
            "id": "abc123",
            "name": "Your Name",
            "email": "[email protected]"
        }
    }
}

Login

POST /api/login

No authentication required. Returns a new API key on success.

Important

Login generates a new API key each time, replacing any existing key. Store the key securely and avoid calling login repeatedly. Accounts with two-factor authentication must generate API keys from the web UI.

ParameterRequiredDescription
emailYesEmail address
passwordYesPassword
cURL
curl -X POST "https://eventschedule.com/api/login" \
     -H "Content-Type: application/json" \
     -d '{"email": "[email protected]", "password": "your_password"}'
Response (200)
{
    "data": {
        "api_key": "your_new_api_key",
        "api_key_expires_at": "2027-02-28T00:00:00Z",
        "user": {
            "id": "abc123",
            "name": "Your Name",
            "email": "[email protected]"
        }
    }
}

List Schedules

GET /api/schedules

Returns a paginated list of your schedules. Supports filtering:

ParameterDescription
nameFilter by schedule name (partial match)
typeFilter by type: venue, talent, or curator
cURL
curl -X GET "https://eventschedule.com/api/schedules?type=venue" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": [
        {
            "id": "abc123",
            "subdomain": "my-venue",
            "name": "My Venue",
            "type": "venue",
            "email": "[email protected]",
            "timezone": "America/New_York",
            ...
        }
    ],
    "meta": { "current_page": 1, "total": 5 }
}

Show Schedule

GET /api/schedules/{subdomain}

Returns a single schedule by subdomain, including its sub-schedules. Requires owner or admin access.

cURL
curl -X GET "https://eventschedule.com/api/schedules/my-venue" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": {
        "id": "abc123",
        "subdomain": "my-venue",
        "name": "My Venue",
        "type": "venue",
        "groups": [
            { "id": "def456", "name": "Main Stage", "slug": "main-stage" }
        ],
        ...
    }
}

Create Schedule

POST /api/schedules

Create a new schedule. New accounts in hosted mode automatically get a Pro trial.

ParameterRequiredDescription
nameYesSchedule name (max 255 characters)
typeYesSchedule type: venue, talent, or curator
emailNoContact email
descriptionNoMarkdown description
timezoneNoTimezone (e.g., America/New_York)
language_codeNoLanguage code (e.g., en, es, fr)
websiteNoWebsite URL
address1, city, state, postal_code, country_codeNoVenue address fields (for venue type)
cURL
curl -X POST "https://eventschedule.com/api/schedules" \
     -H "X-API-Key: your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{"name": "My Venue", "type": "venue", "city": "New York"}'

Update Schedule

PUT /api/schedules/{subdomain}

Update a schedule. Only include fields you want to change. Requires Pro plan and owner or admin access. Subdomain cannot be changed via API.

cURL
curl -X PUT "https://eventschedule.com/api/schedules/my-venue" \
     -H "X-API-Key: your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{"name": "Updated Name", "description": "New description"}'

Delete Schedule

DELETE /api/schedules/{subdomain}

Permanently delete a schedule and all associated data. Requires schedule owner access (not just admin).

cURL
curl -X DELETE "https://eventschedule.com/api/schedules/my-venue" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": {
        "message": "Schedule deleted successfully"
    }
}

List Sub-Schedules

GET /api/schedules/{subdomain}/groups

List all sub-schedules for a schedule. Returns id, name, slug, and color for each.

cURL
curl -X GET "https://eventschedule.com/api/schedules/my-venue/groups" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": [
        {
            "id": "def456",
            "name": "Main Stage",
            "slug": "main-stage",
            "color": "#FF5733"
        }
    ]
}

Create Sub-Schedule

POST /api/schedules/{subdomain}/groups

Create a sub-schedule within a schedule. Requires Pro plan. Slug is auto-generated from the name. Names are auto-translated if the schedule language is not English.

ParameterRequiredDescription
nameYesSub-schedule name
colorNoDisplay color (e.g., #FF5733)
cURL
curl -X POST "https://eventschedule.com/api/schedules/my-venue/groups" \
     -H "X-API-Key: your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{"name": "Main Stage", "color": "#FF5733"}'
Response (201)
{
    "data": {
        "id": "def456",
        "name": "Main Stage",
        "slug": "main-stage",
        "color": "#FF5733"
    }
}

Update Sub-Schedule

PUT /api/schedules/{subdomain}/groups/{group_id}

Update a sub-schedule's name or color. Requires Pro plan.

cURL
curl -X PUT "https://eventschedule.com/api/schedules/my-venue/groups/def456" \
     -H "X-API-Key: your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{"name": "VIP Stage", "color": "#3B82F6"}'

Delete Sub-Schedule

DELETE /api/schedules/{subdomain}/groups/{group_id}

Delete a sub-schedule. Events assigned to this sub-schedule will have their sub-schedule reference cleared. Requires Pro plan.

cURL
curl -X DELETE "https://eventschedule.com/api/schedules/my-venue/groups/def456" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": {
        "message": "Sub-schedule deleted successfully"
    }
}

List Events

GET /api/events

Returns a paginated list of your events, sorted by start date (newest first). Supports filtering:

ParameterDescription
subdomainFilter events by schedule subdomain
starts_afterEvents starting after this date (Y-m-d)
starts_beforeEvents starting before this date (Y-m-d)
venue_idFilter by venue (encoded venue schedule ID)
category_idFilter by category ID
nameFilter by event name (partial match)
schedule_typeFilter by type: single or recurring
tickets_enabledFilter by whether tickets are enabled (boolean)
rsvp_enabledFilter by whether RSVP/registration is enabled (boolean)
group_idFilter by sub-schedule (encoded sub-schedule ID)
cURL
curl -X GET "https://eventschedule.com/api/events?subdomain=my-venue&starts_after=2025-01-01" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": [
        {
            "id": "evt123",
            "name": "Jazz Night",
            "starts_at": "2025-03-15 20:00:00",
            "duration": 3,
            "tickets_enabled": true,
            "rsvp_enabled": false,
            ...
        }
    ],
    "meta": { "current_page": 1, "total": 25 }
}

Show Event

GET /api/events/{id}

Returns a single event by encoded ID, including tickets, members, and agenda parts.

cURL
curl -X GET "https://eventschedule.com/api/events/evt123" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": {
        "id": "evt123",
        "name": "Jazz Night",
        "starts_at": "2025-03-15 20:00:00",
        "duration": 3,
        "tickets": [
            { "id": "tkt1", "type": "General", "price": 25, "quantity": 100 }
        ],
        "event_parts": [
            { "name": "Opening Act", "start_time": "20:00" }
        ],
        ...
    }
}

Create Event

POST /api/events/{subdomain}

Create a new event on a schedule. Requires Pro plan and owner or admin access.

ParameterRequiredDescription
nameYesEvent name
starts_atYesStart date/time in your timezone (Y-m-d H:i:s)
durationNoDuration in hours (0 to 24)
descriptionNoFull description (Markdown supported, max 10000 characters)
short_descriptionNoShort description (max 500 characters)
event_urlNoEvent or livestream URL
registration_urlNoExternal registration URL
event_passwordNoPassword to protect the event page
is_privateNoMake event private (hidden from calendar)
rsvp_enabledNoEnable free RSVP/registration (boolean)
rsvp_limitNoMaximum number of registrations (integer, min 1)
category_idNoCategory ID (see List Categories)
categoryNoCategory name (alternative to category_id)
scheduleNoSub-schedule slug to assign the event to
schedule_typeNosingle or recurring
recurring_frequencyNoFor recurring: daily, weekly, every_n_weeks, monthly_date, monthly_weekday, yearly
recurring_intervalNoWeek interval for every_n_weeks frequency (min 2)
recurring_end_typeNoHow recurrence ends: never, on_date, or after_events
recurring_end_valueNoEnd date (Y-m-d) or count, based on recurring_end_type
tickets_enabledNoEnable ticketing (boolean)
ticket_currency_codeNo3-letter ISO currency code (e.g., USD)
payment_methodNoPayment method: stripe, invoiceninja, payment_url, or manual
payment_instructionsNoPayment instructions (max 5000 characters)
ticketsNoArray of ticket types: [{type, quantity, price, description}]
event_partsNoAgenda parts: [{name, description, start_time, end_time}]
membersNoArray of performers: [{name, email}]
venue_idNoEncoded venue schedule ID
venue_nameNoVenue name (with venue_address1 for auto-matching)
venue_address1NoVenue address (with venue_name for auto-matching)
cURL
curl -X POST "https://eventschedule.com/api/events/my-venue" \
     -H "X-API-Key: your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
         "name": "Jazz Night",
         "starts_at": "2026-03-24 20:00:00",
         "duration": 3,
         "description": "A wonderful evening of jazz music.",
         "tickets_enabled": true,
         "tickets": [
             {"type": "General Admission", "price": 25, "quantity": 100},
             {"type": "VIP", "price": 50, "quantity": 20}
         ],
         "event_parts": [
             {"name": "Opening Act", "start_time": "20:00", "end_time": "20:45"},
             {"name": "Main Performance", "start_time": "21:00", "end_time": "23:00"}
         ]
     }'

Update Event

PUT /api/events/{id}

Update an event. Accepts the same parameters as Create Event. Supports partial updates - only include the fields you want to change. Recurring configuration, tickets, and agenda parts are preserved when not included in the request. Requires Pro plan.

cURL
curl -X PUT "https://eventschedule.com/api/events/evt123" \
     -H "X-API-Key: your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{"name": "Updated Jazz Night", "duration": 4}'

Delete Event

DELETE /api/events/{id}

Permanently delete an event. This also removes it from Google Calendar and CalDAV if synced.

cURL
curl -X DELETE "https://eventschedule.com/api/events/evt123" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": {
        "message": "Event deleted successfully"
    }
}

Upload Flyer

POST /api/events/flyer/{event_id}

Upload a flyer image for an event. Send as multipart form data with a flyer_image field.

cURL
curl -X POST "https://eventschedule.com/api/events/flyer/evt123" \
     -H "X-API-Key: your_api_key_here" \
     -F "flyer_image=@/path/to/flyer.jpg"
Response (200)
{
    "data": { ... },
    "meta": {
        "message": "Flyer uploaded successfully"
    }
}

List Categories

GET /api/categories

Returns all available event categories with their IDs and names. Use the id when creating or updating events.

cURL
curl -X GET "https://eventschedule.com/api/categories" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": [
        {"id": 1, "name": "Art & Culture"},
        {"id": 2, "name": "Business Networking"},
        {"id": 3, "name": "Community"},
        {"id": 4, "name": "Concerts"},
        ...
    ]
}

List Sales

GET /api/sales

Returns a paginated list of sales for events you own or administer. Supports filtering:

ParameterDescription
event_idFilter by event (encoded event ID)
subdomainFilter by schedule subdomain
statusFilter by status: unpaid, paid, cancelled, refunded, or expired
emailFilter by buyer email (exact match)
event_dateFilter by event date (Y-m-d)
cURL
curl -X GET "https://eventschedule.com/api/sales?status=paid&subdomain=my-venue" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": [
        {
            "id": "sale123",
            "event_name": "Jazz Night",
            "name": "John Doe",
            "email": "[email protected]",
            "status": "paid",
            "payment_amount": 50,
            "tickets": [
                { "type": "General", "quantity": 2, "price": 25 }
            ],
            ...
        }
    ],
    "meta": { "current_page": 1, "total": 12 }
}

Show Sale

GET /api/sales/{id}

Returns a single sale by encoded ID, including ticket details.

cURL
curl -X GET "https://eventschedule.com/api/sales/sale123" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": {
        "id": "sale123",
        "event_id": "evt123",
        "event_name": "Jazz Night",
        "name": "John Doe",
        "email": "[email protected]",
        "status": "paid",
        "payment_amount": 50,
        "total_quantity": 2,
        "tickets": [
            { "type": "General", "quantity": 2, "price": 25 }
        ]
    }
}

Create Sale

POST /api/sales

Create a new sale manually for an event. Sales are created as unpaid (free tickets are auto-marked as paid).

ParameterRequiredDescription
event_idYesEncoded event ID
nameYesCustomer name
emailYesCustomer email
ticketsYesObject mapping ticket identifiers to quantities. Keys can be encoded ticket IDs or ticket type names.
event_dateNoEvent date in Y-m-d format (default: event start date)
cURL
curl -X POST "https://eventschedule.com/api/sales" \
     -H "X-API-Key: your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
         "event_id": "evt123",
         "name": "John Doe",
         "email": "[email protected]",
         "tickets": {"General Admission": 2}
     }'

Update Sale Status

PUT /api/sales/{id}

Perform a status action on a sale. Available actions depend on the current status.

ActionFrom StatusTo Status
mark_paidunpaidpaid
refundpaidrefunded
cancelunpaid, paidcancelled
cURL
curl -X PUT "https://eventschedule.com/api/sales/sale123" \
     -H "X-API-Key: your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{"action": "mark_paid"}'

Delete Sale

DELETE /api/sales/{id}

Soft-delete a sale. The sale will no longer appear in listings.

cURL
curl -X DELETE "https://eventschedule.com/api/sales/sale123" \
     -H "X-API-Key: your_api_key_here"
Response (200)
{
    "data": {
        "message": "Sale deleted successfully"
    }
}

Error Handling

The API uses standard HTTP status codes and returns error messages in JSON format.

CodeDescription
200Success
201Created
401Unauthorized (invalid or missing API key)
403Forbidden (insufficient permissions or Pro required)
404Not found
422Validation error (includes field-level errors)
429Rate limit exceeded
500Server error
Validation Error (422)
{
    "error": "Validation failed",
    "errors": {
        "name": ["The name field is required."],
        "starts_at": ["The starts at must match the format Y-m-d H:i:s."]
    }
}

See Also