> ## Documentation Index
> Fetch the complete documentation index at: https://docs.laces.run/llms.txt
> Use this file to discover all available pages before exploring further.

# List events

> Your organization's races that are on sale, soonest first.



## OpenAPI

````yaml api-reference/v1/openapi.json GET /events
openapi: 3.1.0
info:
  title: Laces Partner API
  version: 1.0.0
  summary: Show your organization's races and sell entries from your own website.
  description: >-
    The Laces Partner API, served at `https://connect.laces.run/v1`. Every path
    is relative to that server URL, which already ends in `/v1`.


    Authenticate with a **bearer token** from `POST /oauth/token` (server side)
    or, on the routes that allow it, a **publishable key** in
    `X-Laces-Publishable-Key` (browser side, from an allowed domain). Keys are
    uppercase and case-sensitive: send them exactly as issued.


    There is one environment, production. Payments made through the API are
    real.


    Money is integer minor units. Every route except the token endpoint answers
    in the Laces envelope `{ code, message, data | error, error_code }`; branch
    on `error_code`, never on `message` or `error`.


    Every response carries an `X-Request-Id` header (`req_…`). Quote it to
    support@laces.run when something goes wrong. Browsers can read
    `X-Request-Id` and `Retry-After` (both are CORS-exposed). Rate-limited
    routes also send the standard `RateLimit-Limit`, `RateLimit-Remaining` and
    `RateLimit-Reset` headers.


    Partner credentials are accepted on this host only. Sent to `api.laces.run`
    (the Laces app's own API), any partner credential is refused with `401
    partner_credential_not_accepted`.
  contact:
    name: Laces support
    email: support@laces.run
    url: https://docs.laces.run
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
  - url: https://connect.laces.run/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Authentication
    description: OAuth 2.0 client credentials.
  - name: Events
    description: Your organization's races that are on sale.
  - name: Checkout sessions
    description: 'Laces-hosted checkout: redirect or embedded.'
  - name: Orders
    description: Create, pay and read orders from your own UI.
  - name: Webhook events
    description: Requests Laces sends to your webhook endpoint.
  - name: Health
    description: Liveness probe.
paths:
  /events:
    get:
      tags:
        - Events
      summary: List events
      description: >-
        Your organization's events that can be sold: status `scheduled` or
        `open`, visibility `public` or `unlisted`, not ended, not demo, not
        code-locked. Soonest first.


        Works with a bearer token or a publishable key (from a browser on an
        allowed domain). Scope `events:read`.
      operationId: listEvents
      parameters:
        - name: limit
          in: query
          description: 1 to 50. Larger values are clamped to 50.
          schema:
            type: integer
            minimum: 1
            default: 20
        - name: cursor
          in: query
          description: '`next_cursor` from the previous page.'
          schema:
            type: string
      responses:
        '200':
          description: A page of events.
          content:
            application/json:
              schema:
                type: object
                required:
                  - code
                  - message
                  - data
                properties:
                  code:
                    type: integer
                    description: HTTP status, repeated in the body.
                    examples:
                      - 200
                  message:
                    type: string
                    examples:
                      - Events retrieved successfully
                  data:
                    type: object
                    properties:
                      events:
                        type: array
                        items:
                          $ref: '#/components/schemas/EventSummary'
                      next_cursor:
                        type: string
                        description: Omitted on the last page.
                      has_more:
                        type: boolean
                    required:
                      - events
                      - has_more
              example:
                code: 200
                message: Events retrieved successfully
                data:
                  events:
                    - event_id: q3Zk9mVx
                      name: Kampala City 10K
                      handle: kampala-city-10k
                      short_code: K10
                      description: A flat, fast 10K through the city centre.
                      cover: https://laces.run/images/example-cover.jpg
                      venue: Kololo Airstrip
                      event_type: run
                      status: open
                      visibility: public
                      starts_at: '2026-11-15T04:00:00.000Z'
                      ends_at: '2026-11-15T09:00:00.000Z'
                      timezone: Africa/Kampala
                      currency: UGX
                      reg_opens_at: '2026-09-01T00:00:00.000Z'
                      reg_closes_at: '2026-11-13T20:00:00.000Z'
                      payments_enabled: true
                  next_cursor: eyJpZCI6InEzWms5bVZ4In0
                  has_more: true
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          description: Bad `limit` or cursor.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                invalid_request:
                  summary: invalid_request
                  value:
                    code: 400
                    message: Validation failed
                    error: limit must be a positive integer
                    error_code: invalid_request
                invalid_cursor:
                  summary: invalid_cursor
                  value:
                    code: 400
                    message: Validation failed
                    error: Invalid cursor
                    error_code: invalid_cursor
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
      security:
        - bearerAuth: []
        - oauth2:
            - events:read
        - publishableKey: []
components:
  schemas:
    EventSummary:
      type: object
      properties:
        event_id:
          type: string
          examples:
            - q3Zk9mVx
        name:
          type: string
          examples:
            - Kampala City 10K
        handle:
          type: string
          examples:
            - kampala-city-10k
        short_code:
          type: string
          examples:
            - K10
        description:
          type: string
        cover:
          type: string
          description: Cover image URL.
          format: uri
        venue:
          type: string
          description: Omitted when not set.
        event_type:
          type: string
          examples:
            - run
        status:
          type: string
          enum:
            - scheduled
            - open
        visibility:
          type: string
          description: Unlisted events are included on purpose.
          enum:
            - public
            - unlisted
        starts_at:
          type: string
          format: date-time
        ends_at:
          type: string
          format: date-time
        timezone:
          type: string
          examples:
            - Africa/Kampala
        currency:
          type: string
          examples:
            - UGX
        reg_opens_at:
          type: string
          description: Omitted when not set.
          format: date-time
        reg_closes_at:
          type: string
          description: Omitted when not set.
          format: date-time
        payments_enabled:
          type: boolean
          description: >-
            Organization-level. `false` means your organization is not yet
            cleared to take payments: the event stays readable, but orders and
            checkout sessions are refused with `403 payments_disabled`.
      required:
        - event_id
        - name
        - handle
        - short_code
        - description
        - cover
        - event_type
        - status
        - visibility
        - starts_at
        - ends_at
        - timezone
        - currency
        - payments_enabled
    Error:
      type: object
      properties:
        code:
          type: integer
          description: HTTP status, repeated in the body.
        message:
          type: string
          description: Short outcome. Do not branch on it; it may be reworded.
        error:
          type: string
          description: Human-readable detail. May be reworded; never parse it.
        error_code:
          type: string
          description: >-
            Stable machine-readable code. **Branch on this.** Present on every
            Partner API error, including `429 rate_limited`, `404 not_found` for
            unknown routes and `500 server_error`. See the [error
            reference](/concepts/errors).
        details:
          type: object
          properties:
            retry_after_seconds:
              type: integer
          description: Only on `409 prompt_in_progress`.
      required:
        - code
        - message
        - error
        - error_code
      description: The Laces error envelope.
  headers:
    X-Request-Id:
      description: >-
        Unique id of this request (`req_…`). On every response, readable from
        browsers. Quote it to support.
      schema:
        type: string
      example: req_V1StGXR8Z5jdHi6BmyTq
    Retry-After:
      description: Whole seconds to wait before retrying. Readable from browsers.
      schema:
        type: integer
    RateLimit-Limit:
      description: Requests allowed in the current window.
      schema:
        type: integer
    RateLimit-Remaining:
      description: Requests left in the current window.
      schema:
        type: integer
    RateLimit-Reset:
      description: Seconds until the window resets.
      schema:
        type: integer
  responses:
    Unauthorized:
      description: >-
        No credential, an invalid or expired token, or an invalid publishable
        key. Comes with `WWW-Authenticate: Bearer realm="laces-partner"`.
        Revoking or regenerating keys can take up to a minute to reach every
        server.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            unauthorized:
              summary: unauthorized
              value:
                code: 401
                message: Unauthorized
                error: Missing credentials
                error_code: unauthorized
            invalid_token:
              summary: invalid_token
              value:
                code: 401
                message: Unauthorized
                error: Invalid or expired access token
                error_code: invalid_token
            invalid_key:
              summary: invalid_key
              value:
                code: 401
                message: Unauthorized
                error: Invalid publishable key
                error_code: invalid_key
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
    Forbidden:
      description: >-
        The credential is not allowed here: a missing scope (scope changes take
        up to about a minute to apply), a publishable key on a bearer-only
        route, or a publishable key from an origin that is not an allowed
        domain.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            insufficient_scope:
              summary: insufficient_scope
              value:
                code: 403
                message: Forbidden
                error: 'Missing scope: orders:read'
                error_code: insufficient_scope
            credential_not_permitted:
              summary: credential_not_permitted
              value:
                code: 403
                message: Forbidden
                error: This endpoint does not accept a publishable key
                error_code: credential_not_permitted
            origin_not_allowed:
              summary: origin_not_allowed
              value:
                code: 403
                message: Forbidden
                error: This origin is not allowed for this key
                error_code: origin_not_allowed
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
    RateLimited:
      description: >-
        Rate limited. Wait `Retry-After` seconds. Limits are per API client
        (reads about 300 a minute, writes about 60) and, for publishable keys,
        also per IP (about 120 a minute).
      headers:
        Retry-After:
          $ref: '#/components/headers/Retry-After'
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimit-Limit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimit-Remaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimit-Reset'
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: 429
            message: Too many requests, please slow down
            error: rate_limited
            error_code: rate_limited
    ServerError:
      description: >-
        Unexpected failure. Retry with backoff, reusing the same
        `Idempotency-Key`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            server_error:
              summary: server_error
              value:
                code: 500
                message: An unexpected error occurred
                error: Something went wrong
                error_code: server_error
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: LCSTOK-…-X (opaque)
      description: >-
        A token from `POST /oauth/token`, valid 1 hour. Paste it as `LCSTOK-…-X`
        (without the word Bearer).
    oauth2:
      type: oauth2
      description: >-
        OAuth 2.0 client credentials. The token it yields is the `bearerAuth`
        token.
      flows:
        clientCredentials:
          tokenUrl: https://connect.laces.run/v1/oauth/token
          scopes:
            events:read: List and read events
            orders:write: Create and pay orders
            orders:read: >-
              List and read orders, including buyer personal data (off by
              default)
            checkout_sessions:write: Create and read checkout sessions
    publishableKey:
      type: apiKey
      in: header
      name: X-Laces-Publishable-Key
      description: >-
        Browser-safe key `LCSPUBK-…-X`. Only works from a browser whose `Origin`
        is one of your allowed domains, and is capped to `events:read` and
        creating checkout sessions. **"Try it" with a publishable key fails in
        this playground** (`403 origin_not_allowed`): the request carries no
        allowed `Origin`. Use a bearer token here.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.