Using the API
Everything you can see and do on Arcane City is also available as JSON, so you can build scripts, importers, bots, and apps on top of it.
This page is the plain-language introduction. The full endpoint reference lives at /api/docs.
Last updated: September 2026 · Back to Help
What the API is
A JSON REST API over the same data the site shows: events, entities (venues, artists, promoters, DJs…), series, tags, photos, links, contacts, forum threads, posts, blogs, and more.
- Base URL:
https://api.arcane.city/api - Format: requests and responses are JSON. Send
Accept: application/jsonon every request so errors come back as JSON too. - Reference: every endpoint, parameter, and response shape is listed at /api/docs.
Your account is your API account
There is no separate developer signup. If you have a site account, you already have API access: register if you don't.
API calls run as your user, with exactly the same permissions and visibility rules as the website:
- You see public content, plus any private content you'd be able to see when logged in.
- You can edit or delete only what you own, unless your account has admin rights.
- Anything you create is attributed to your account.
In short: if you can't do it in the browser, you can't do it through the API either.
Authentication
Most endpoints require you to identify yourself. There are two ways to do it.
Option 1: HTTP Basic auth
Send your site email and password on each request (Authorization: Basic base64(email:password)). It's the simplest option for quick scripts. Most tools handle the encoding for you:
curl -u 'you@example.com:your-password' \
-H 'Accept: application/json' \
https://api.arcane.city/api/events
Option 2: Bearer token
If you'd rather not store your password in a script, exchange it once for a token and send that instead.
-
Create a token with basic auth and a
token_nameof your choice:
The token is shown only once, so save it somewhere safe.curl -u 'you@example.com:your-password' \ -H 'Accept: application/json' \ -d 'token_name=my-importer' \ https://api.arcane.city/api/tokens/create # => {"token": "12|AbCdEf..."} -
Send it as a bearer token:
curl -H 'Authorization: Bearer 12|AbCdEf...' \ -H 'Accept: application/json' \ https://api.arcane.city/api/auth/meGET /api/auth/mereturns the user the token belongs to, which is a handy way to check it works. -
To revoke tokens, call
GET /api/tokens/invalidatewith a token. It deletes all of your tokens, not just that one.
A token grants the same access as your account. Scoped or read-only tokens aren't available, so treat a token like your password.
Reading data
Each kind of record has a list endpoint and a single-record endpoint, for example
GET /api/events,
GET /api/events/{id},
GET /api/entities,
GET /api/series, and
GET /api/tags.
Paging
page: which page to return, starting at 1.limit: results per page, up to 1000.- List responses include
datapluscurrent_page,last_page,total, andnext_page_url. Keep followingnext_page_urluntil it'snull.
Sorting
sort takes a column, for example events.start_at or entities.name. direction is asc or desc.
Filtering
Filters use filters[field]=value. Some useful ones:
filters[name]=…: name contains the text.filters[tag]=techno,house: has any of these tags.filters[tag_all]=techno,house: has all of these tags.filters[venue]=…: events at a venue, matched by its slug (events only).filters[start_at][start]=2026-10-01&filters[start_at][end]=2026-10-31: events starting in a date range.filters[entity_type]=venue: entities of one type, matched by the type's slug (entities only).
See /api/docs for the filters each endpoint supports.
# Techno events in October 2026, soonest first, 50 per page
curl -G -u 'you@example.com:your-password' \
-H 'Accept: application/json' \
--data-urlencode 'filters[tag]=techno' \
--data-urlencode 'filters[start_at][start]=2026-10-01' \
--data-urlencode 'filters[start_at][end]=2026-10-31' \
-d 'sort=events.start_at' -d 'direction=asc' -d 'limit=50' \
https://api.arcane.city/api/events
Writing data
Create records with POST to the list endpoint (for example POST /api/events). Replace a record with PUT /api/events/{id}, or change only some fields with PATCH /api/events/{id}. The same rules apply as on the site's forms: required fields, validation messages, and ownership checks. Validation errors come back as 422 with a message for each field.
curl -u 'you@example.com:your-password' \
-H 'Accept: application/json' -H 'Content-Type: application/json' \
-d '{
"name": "Basement Session",
"slug": "basement-session",
"start_at": "2026-10-17 21:00:00",
"event_type_id": 1,
"visibility_id": 3,
"tag_list": ["techno", 42]
}' \
https://api.arcane.city/api/events
Look up valid ids with GET /api/event-types, GET /api/visibilities, GET /api/entity-types, and so on.
Tags
tag_listaccepts existing tag ids, tag names, or a mix of both.- Names match existing tags regardless of capitalization, so
"diy"and"DIY"are the same tag. A new tag is created only when nothing matches. - On
PUT, leaving outtag_listremoves all tags. OnPATCH, tags change only when you sendtag_list.
Photos
- Upload:
POST /api/events/{id}/photoswith a multipartfilefield. This also works forentitiesandseries. - From a URL:
POST /api/events/{id}/photos/from-urlwith{"url": "https://…"}. The server downloads the image for you. The URL must be public https, and the image must be a jpg, png, gif, or webp of 5 MB or less. - You can add photos only to records you own (or any record, as an admin). The first photo becomes the primary image.
Rate limits & etiquette
- 240 requests per minute per logged-in user (basic auth or token).
- 120 requests per minute per IP address for requests that aren't logged in.
- Adding photos by URL has its own limit of 20 requests per minute per user.
- After 20 failed logins in a minute from one IP address, basic auth from that address is refused until the minute is up, even with the right password. If your script keeps failing to log in, check your credentials before retrying.
- Every response includes
X-RateLimit-Remaining. Over a limit you'll get429 Too Many Requestswith aRetry-Afterheader saying how many seconds to wait. - This is a community-run site on modest hardware. Page through results instead of requesting huge lists, cache what you can, and space out bulk imports.
- Check for existing events, entities, and series before creating new ones so you don't make duplicates.
- Everything you create through the API is covered by the Terms of Service, just like content added through the site.
Where to go next
- /api/docs: the full endpoint reference.
- github.com/geoff-maddock/events-tracker: the source code. Report API bugs in GitHub issues.
- Help & Tutorials: how the site works (events, entities, series, tags).