> ## 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.

# Laces Partner API

> Show your organization's races on your own website and sell entries, with a hosted page, an embedded modal or your own checkout.

The Laces Partner API is for developers working on behalf of a Laces
organizer. With it you can:

* **List your organization's races** and show them on your own website, with
  ticket types, prices and the exact fees a participant pays.
* **Take registrations and payment** for those races: MTN Mobile Money and
  Airtel Money today, card coming soon. Laces handles the money, the tickets
  and the receipts.
* **Hear about payment outcomes** through signed webhooks.

Everything else (the dashboard, payouts, participant management, refunds, the
team) stays in the Laces app. The API is deliberately small.

<Note>
  One organization has its own API clients, and a credential only ever sees
  its own organization's events and orders. There are no multi-organization
  partner accounts.
</Note>

## Three ways to integrate

<Columns cols={3}>
  <Card title="Hosted checkout" icon="arrow-up-right-from-square" href="/guides/hosted-checkout">
    Add a **Register** button. The buyer pays on a Laces page and comes back to
    your site. Works on a static site.
  </Card>

  <Card title="Embedded checkout" icon="window-restore" href="/guides/embedded-checkout">
    Add one `<script>` tag. Laces checkout opens in a modal on top of your page.
    **New.**
  </Card>

  <Card title="Custom UI" icon="code" href="/guides/custom-ui">
    Build your own event pages and checkout form. Your server calls the API with
    an OAuth token.
  </Card>
</Columns>

| | Hosted checkout | Embedded checkout | Custom UI |
| - | - | - | - |
| What you build | A button that redirects | A button that opens a modal | Event pages and a checkout form |
| Credential in the browser | Publishable key | Publishable key | None |
| Needs a backend | Only to verify the result | Only to verify the result | Yes |
| Payment page | Laces (`laces.run/checkout/…`) | Laces, inside a modal on your page | Yours (mobile money) |
| Buyer leaves your site | Yes, then returns | No | No |
| How you learn the result | Return URL, then verify on your server; webhooks | `onSuccess`, then verify on your server; webhooks | Webhooks or order reads |

**Which should I pick?**

* Start with **hosted checkout** if you want the least work. It is the most
  battle-tested path, handles every payment method, and your site never touches
  payment details.
* Pick **embedded checkout** if you want the same Laces checkout without the
  buyer leaving your page.
* Pick **custom UI** if you need full control of the look and flow, and you
  have a server to hold the client secret.

You can combine them, for example a custom event listing with hosted checkout
for payment.

## How the pieces fit

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant B as Buyer's browser
    participant S as Your server
    participant L as Laces API (connect.laces.run)
    participant P as laces.run checkout

    rect rgba(119, 215, 4, 0.08)
    Note over B,P: Hosted or embedded checkout (publishable key)
    B->>L: POST /checkout-sessions (X-Laces-Publishable-Key)
    L-->>B: { id, url }
    B->>P: Redirect to url (hosted) or open it in a modal (embedded)
    P-->>B: Buyer registers and pays
    P-->>B: Return to on_success_url, or onSuccess callback
    B->>S: Session id
    S->>L: GET /checkout-sessions/{id} (Bearer token)
    L-->>S: status: complete
    end

    rect rgba(63, 122, 18, 0.08)
    Note over B,P: Custom UI (OAuth client credentials, server only)
    S->>L: POST /oauth/token
    L-->>S: access_token (1 hour)
    S->>L: GET /events/{id}
    B->>S: Buyer picks tickets and enters details
    S->>L: POST /orders (Idempotency-Key)
    S->>L: POST /orders/{id}/pay
    L-->>B: Mobile money prompt on the buyer's phone
    end

    L-)S: Webhook order.paid (signed)
```

## Two kinds of credential

| Credential | Looks like | Where it lives | What it can do |
| - | - | - | - |
| Publishable key | `LCSPUBK-…-X` | Your web page. Public by design. | List and read events, create a checkout session. Only from your allowed domains. |
| Client id + client secret | `LCSCLI-…` + `LCSSECK-…-X` | Your server only | Exchanged for a 1-hour bearer token that can do everything your scopes allow, including creating and paying orders. |

See [Getting your API keys](/api-keys) and [Authentication](/authentication).

## Base URL

| Environment | Base URL |
| - | - |
| Production | `https://connect.laces.run/v1` |

Every path in these docs is relative to the base URL, so
`POST /oauth/token` means `POST https://connect.laces.run/v1/oauth/token`.
Code samples use `$BASE` (or `LACES_BASE`) for it. There is one environment:
you build and test against production with your live keys. See
[Testing your integration](/concepts/testing).

## Conventions

* JSON in, JSON out, `snake_case` field names.
* **Money is an integer in minor units**, never a float. Always read the
  event's `currency`. (UGX has no minor unit, so `50000` UGX is fifty thousand
  shillings.)
* Timestamps are ISO 8601 UTC strings, for example `2026-11-15T04:00:00.000Z`.
* Every response carries `Cache-Control: private, no-store` and an
  `X-Request-Id` header. Quote the request id when you contact support.
* Every route except the token endpoint uses the Laces response envelope
  (`code`, `message`, `data`, and on failure `error` plus a stable
  `error_code`). See [Errors](/concepts/errors).

## Next steps

<Columns cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Keys, your first event list and a working checkout in about ten minutes.
  </Card>

  <Card title="API reference" icon="square-terminal" href="/api-reference/v1/introduction">
    Every endpoint, with a live "Try it" playground.
  </Card>
</Columns>


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