Version 1

loso API

Read-only HTTP access to the events corpus behind loso: what is on, where, when, and what it costs. JSON over HTTPS, one bearer token, four endpoints. The reference documents all of them.

Base URL

https://api.locally-social.com/api/v1

Quickstart

Three steps, and the second one is the whole API surface.

1. Get a key

Access is reviewed by hand. Apply from the developer portal — it asks what you are building and what you will do with the data, which is the answer the review turns on. An approved account mints its own keys; nobody emails you one.

Keys look like lsk_ followed by a secret. The secret is shown once, at mint time, and is never retrievable again.

2. Make a request

Every request carries the key as a bearer token. Nothing else is required.

curl "https://api.locally-social.com/api/v1/events?city=Charlotte&state=NC" \
  -H "Authorization: Bearer $LOSO_API_KEY"
200 application/json
{
  "data": [
    {
      "id": "9f1c6b4e-2a71-4d58-9c33-0e5a7b812d04",
      "title": "Thursday Night Trivia",
      "description": "Six rounds, teams of up to six, no phones.",
      "start_at": "2026-11-05T23:30:00Z",
      "end_at": null,
      "time_tbd": false,
      "categories": ["Trivia & Games"],
      "is_recurring": true,
      "recurrence_pattern": "Weekly on Thursday",
      "price": 0,
      "ticket_url": null,
      "image_url": "https://cdn.locally-social.com/events/9f1c6b4e.jpg",
      "is_sold_out": false,
      "url": "https://locally-social.com/events/charlotte-nc/thursday-night-trivia-9f1c6b4e2a71",
      "updated_at": "2026-11-01T14:02:11Z",
      "venue": {
        "id": "c4e81a92-7f30-4b6d-85a1-2d9e03f7b418",
        "name": "Selwyn Avenue Taproom",
        "address": "2801 Selwyn Ave",
        "city": "Charlotte",
        "state": "NC",
        "neighborhood": "Myers Park",
        "latitude": 35.1823,
        "longitude": -80.8471
      }
    }
  ],
  "next_cursor": "MjAyNi0xMS0wNVQyMzozMDowMCswMDowMHw5ZjFjNmI0ZQ"
}

3. Page

List responses are cursor-paged. Send next_cursor back as cursor until it comes back null.

# One page at a time; feed next_cursor back in.
curl "https://api.locally-social.com/api/v1/events?city=Charlotte&state=NC&limit=50" \
  -H "Authorization: Bearer $LOSO_API_KEY"

curl "https://api.locally-social.com/api/v1/events?city=Charlotte&state=NC&limit=50&cursor=MjAyNi0xMS0wNVQ..." \
  -H "Authorization: Bearer $LOSO_API_KEY"

Tiers

What a key may read is a property of the account, not of the key — minting a new one does not widen access.

TierReadsLimits
TrialGranted on approval. Real keys, real rows, one ZIP.ZIP 28209 (Charlotte, NC)30/min · 1,000/day · 1 key
LiveGranted once there is something built against the trial.The whole corpus60/min · 10,000/day · 2 keys
PartnerVolume agreed per partner. Not self-serve.The whole corpus600/min · 250,000/day · 5 keys

Page size caps with the tier too — 25, 50 and 200 rows. A larger limit is clamped to the cap rather than refused, so a request asking for more than a tier gives still answers with a cursor to continue.

Versioning

/api/v1 answers the shapes documented here for as long as it exists. Fields may be added. Nothing is renamed, removed or re-typed — a change that cannot be made additively ships as /api/v2 running beside this one.

Two things that follow, both worth coding against: decode JSON permissively, because a new field is not a breaking change; and treat next_cursor as opaque, because its contents will change and parsing it is the one way to be broken by a release that kept every promise above.

An OpenAPI 3.1 document for the same surface is served at https://api.locally-social.com/api/v1/openapi.json, with a Swagger console at https://api.locally-social.com/api/v1/docs.

Not in version 1

Writes—
Every endpoint is a GET. There is no scope that grants a write and adding one would be a new scope, reviewed.
A venue collection—
Venues are returned nested inside the events that happen at them. There is no endpoint that pages through venues, so the set of places loso covers cannot be walked.
Attendance—
No RSVP counts, no rosters, no saves. Per-event engagement across an enumerable corpus is a different disclosure from a count on a page somebody was linked to.
Webhooks—
Poll updated_since instead. It is a filter on when a row last changed and not a change feed — see the reference for what that does and does not guarantee.
Ticketing—
An event carries ticket_url and price. Orders, inventory and anything about a loso account are not served.
loso API — local events data as JSON