Skip to content

Get started

Conventions

Time fields, ids, booleans, prices and the response envelope every endpoint shares.

Every endpoint follows the same rules for time, ids, booleans, prices and the response envelope. Learn them once here.

Requests

  • Base URL: https://api.tailend.dev. Every data endpoint is a GET under /v1; the API is read-only, and any other method returns 405.
  • Send your key in the X-API-Key header. See Authentication.
  • Most paths start with a metro slug: /v1/philadelphia/events. Get the list from GET /v1/metros.
  • List parameters take several values, comma-separated or repeated: audience=teens,families is the same as audience=teens&audience=families.

The response envelope

A list returns data (an array) and meta. A single read returns data (an object). Some responses also carry notices[]: things you should know that did not stop the request, such as an add-on your key is not entitled to.

JSON
{
  "data": [{ "id": "…", "type": "event", "name": "…" }],
  "meta": { "limit": 50, "count": 1, "has_more": false, "next_cursor": null },
  "notices": []
}

Every failure uses one error envelope instead. See Errors.

Time

Field suffixMeaningExample
*_atAn instant in UTC, RFC 3339starts_at: "2026-09-14T13:30:00.000Z"
*_localLocal wall-clock time with no offset; read it against the object's timezonestarts_local: "2026-09-14T09:30:00"
*_onA calendar date with no timestarts_on: "2026-09-14"
  • starts_local is already the time printed on the source page. Never add an offset to it.
  • No field carries a _utc suffix: UTC is what _at means.
  • Date filters such as from and to are local calendar dates in the metro's timezone, inclusive.
  • Some events have no date at all. They have has_date: false, and starts_at and starts_local are null. Check has_date before parsing either.

Ids and slugs

Every listing has a stable id (a UUID) and a human-readable slug. Read a single listing by either: GET /v1/events/{id} or GET /v1/events/slug/{slug}. Every resource also carries links, relative paths to itself and its related collections.

Booleans

Yes-or-no facts are named is_* or has_* (is_free, is_recurring, has_date, has_time). When a source does not say, the value is null: read null as "unknown", never as "no".

Prices

A price is a decimal amount plus a currency, never a formatted string:

JSON
{ "price": { "is_free": false, "min": 12, "max": 12, "currency": "USD" } }

Distances

Distances and radii are in metres: radius_m, distance_m.

Organizations, places and sources

  • An organization runs listings (organization).
  • A place is where a listing happens (place).
  • A source is the page a listing was read from, available with include=source on entitled keys. See Shaping responses.

Stability

v1 is frozen: every path, parameter and field in the reference is a promise. New optional parameters, new fields and new error.code values can appear at any time, so parse permissively. See Audience & versioning.