Ulsav Docs

Quickstart

Make your first public read, fetch one Event, then call an Organization endpoint with an API key.

Two requests need no credential, so start there. The third proves your API key works against Organization data.

The examples use the production host. Swap in https://api.ulsav.dev when you are working against the development stack.

  1. List public Events

    GET/api/v1/events

    Search public Events as a cursor-paginated collection.

    Auth no authentication
    curl -s "https://api.ulsav.com/api/v1/events?limit=2"

    The response is a cursor-paginated collection. This excerpt keeps the fields a card needs and omits required ones such as style, price, and locationPrecision, which every item still carries:

    {
      "data": [
        {
          "id": "01a19fd4-611e-7128-8d77-b7aa8b8ae457",
          "slug": "product-analytics-cohort",
          "name": "Product Analytics Cohort 12",
          "category": "class",
          "participationMode": "online",
          "startAt": "2026-10-31T09:00:00+05:30",
          "endAt": "2026-11-10T09:00:00+05:30",
          "timezone": "Asia/Kolkata",
          "salesPaused": false
        }
      ],
      "meta": {
        "limit": 2,
        "total": 60,
        "hasMore": true,
        "nextCursor": "opaque-cursor-from-the-server"
      }
    }

    nextCursor is opaque. Pass it back as ?cursor= to fetch the next page; do not decode it or construct one yourself.

  2. Fetch one Event

    The public detail route resolves a published Event by slug:

    GET/api/v1/events/{slug}

    Resolve one published Event by its slug.

    Auth no authentication
    curl -s "https://api.ulsav.com/api/v1/events/product-analytics-cohort"
    {
      "id": "01a19fd4-611e-7128-8d77-b7aa8b8ae457",
      "slug": "product-analytics-cohort",
      "name": "Product Analytics Cohort 12",
      "category": "class",
      "timezone": "Asia/Kolkata",
      "participationMode": "online",
      "startAt": "2026-10-31T09:00:00+05:30",
      "endAt": "2026-11-10T09:00:00+05:30",
      "publicationState": "published",
      "salesState": "open",
      "visibility": "public"
    }

    This excerpt also omits required fields such as organizationId, teamMode, registrationPolicy, and the lifecycle timestamps. For the fields it does show:

    FieldPresence
    styleAlways present
    passes, sessions, topicsAlways present, possibly empty
    descriptionOptional
    contactsOptional
    salesStateOptional
    Venue fields such as venueName and venueAddressOptional

    The fields above are enough to render a listing card and link to the Event page.

  3. Call an Organization endpoint

    Create a key in the organizer webapp under Settings → API Keys, with the events.read capability and Organization Scope. Copy the secret when it is shown; it is not retrievable later.

    GET/api/v1/organizations/{organization_id}/events

    List Organization Events, drafts included, within the key's Scope.

    Auth API keyCapability events.read
    export ULSAV_API_KEY="ulsav_sk_..."
    export ULSAV_ORG_ID="01a19fd4-60da-7da4-b972-929a73829aa6" # replace with your Organization id
    
    curl -s "https://api.ulsav.com/api/v1/organizations/$ULSAV_ORG_ID/events?limit=2" \
      -H "Authorization: Bearer $ULSAV_API_KEY"

    You get the same { data, meta } envelope, now containing the drafts and published Events your key is allowed to read. Archived Events appear only when a statuses filter names archived explicitly.

    Credential failures are separated by code, not by status alone:

    SituationStatusCode
    Malformed key401api_key_invalid
    Revoked key401api_key_revoked
    Expired key401api_key_expired
    Valid key without the operation's capability403api_key_forbidden
    Key whose Scope does not cover the target403api_key_scope_denied

    A request with no credential at all fails 401 with the detail authentication required.

Keys belong on the server

An Organization API key can read every Organization record its capability and Scope allow. Keep it in a server-side secret store. If a browser app needs data directly, give it a narrowly scoped key with an origin allowlist, as described in Authentication.

Next: Authentication for the full credential model, or Conventions for pagination and errors in depth.

On this page