> ## Documentation Index
> Fetch the complete documentation index at: https://partner-help.letsdothis.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Public API

> Use the Let's Do This REST API to work with your events, bookings, participants, and related data.

The Let's Do This Public API provides a REST interface for the data you use to plan, promote, and run events. Requests and responses use JSON.

<Warning>
  Keep your API key secret. Do not share it or include it in a public website,
  mobile app, or client-side application.
</Warning>

## Get an API key

Create an API key from the **Settings** → **Credentials** section of your Let's Do This account. Contact your Let's Do This representative if you cannot access this section.

If an API key is exposed, revoke it from the same section and create a replacement.

## Send your first request

Include your API key as a bearer token in the `Authorization` header:

```bash theme={null}
curl --request GET \
  --url "https://api.letsdothis.com/v0/participants" \
  --header "Authorization: Bearer YOUR_API_KEY"
```

Use the production server for live data and the staging server when testing an integration.

| Environment | Base URL                             |
| ----------- | ------------------------------------ |
| Production  | `https://api.letsdothis.com`         |
| Staging     | `https://api.staging.letsdothis.com` |

<Note>
  The code samples on endpoint pages are copyable but do not send requests from
  this documentation site. This prevents API keys from passing through a
  documentation proxy.
</Note>

## Paginated responses

List endpoints return results in `data` and pagination information in `page`:

```json theme={null}
{
  "data": [
    {
      "id": "6399c20015d60ae3ff28f24c"
    }
  ],
  "page": {
    "totalResults": 1,
    "first": "6399c20015d60ae3ff28f24c",
    "last": "64577f3fa6449247e0322e8e",
    "prev": "",
    "next": "64577f3fa6449247e0322e8e"
  }
}
```

Pass `page[after]` or `page[before]` from a response into your next request. Use `page[size]` to control the number of results where the endpoint supports it.

## Optional features

Some endpoints accept a comma-separated `features` query parameter. Features add fields or behavior for one request without changing the default response contract.

For example:

```text theme={null}
GET /v0/participants?features=tags,waves
```

Each endpoint page lists the feature values it supports.

## Error responses

| Status | Meaning                                                                                            |
| ------ | -------------------------------------------------------------------------------------------------- |
| `400`  | The request parameters or body are invalid.                                                        |
| `401`  | The API key is missing, invalid, or revoked.                                                       |
| `403`  | Your organization does not have access to the requested operation.                                 |
| `404`  | The resource does not exist or is not accessible with your API key.                                |
| `429`  | The request exceeded an API rate limit. Retry after the period indicated by the server.            |
| `500`  | The API encountered an unexpected error. Contact your Let's Do This representative if it persists. |

## Rate limiting

Every import endpoint, the registration-status check and the timing ingest endpoint are rate limited, so a request to one can be rejected with a `429`:

* `POST` and `PUT /v0/bookings/line-items/import`
* `POST` and `PUT /v0/add-ons/import`
* `POST /v0/bookings/import`
* `POST /v0/credits/import`
* `POST /v0/discount-codes/import`
* `POST /v0/referrals/import`
* `POST /v0/reserved-entries/participants/import`
* `POST /v0/event-occurrences/{id}/registration-status`
* `POST /timing-inbound/v1`

Limits apply per API key and per endpoint, so a burst against one import does not consume the allowance of another. A few endpoints outside this list carry their own, separate allowances — the `x-ratelimit-*` headers on a response are what tell you a limit applies, so treat `429` as a response any endpoint can return.

Sequential requests are unlikely to be affected. Sending requests in parallel, which is the natural way to drive a bulk import, is what exhausts an allowance.

Every response from these endpoints reports the current state of your allowance:

| Header                  | Meaning                                         |
| ----------------------- | ----------------------------------------------- |
| `x-ratelimit-limit`     | Requests permitted in the current window.       |
| `x-ratelimit-remaining` | Requests still permitted in the current window. |
| `x-ratelimit-reset`     | Seconds until the current window resets.        |

A rejected request also returns a `retry-after` header with the number of seconds to wait:

```json theme={null}
{
  "statusCode": 429,
  "error": "Too Many Requests",
  "message": "Rate limit exceeded, retry in 1 second"
}
```

<Note>
  Treat these headers as the authoritative source rather than hard coding a
  figure. Which endpoints are limited, and how generous each allowance is, can
  change.
</Note>

Handle a `429` by waiting for the period given in `retry-after` and retrying. A rejected request is never processed, so retrying it is safe — no import is partially applied because of a rate limit.

## OpenAPI schema

You can [download the OpenAPI schema](/openapi.json) to use with tools such as Postman or an OpenAPI client generator.

See the [API changelog](/api-reference/changelog) before upgrading an existing integration.
