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

# Scopes

> What each scope allows, which are on by default, and what a publishable key can never do.

Scopes are set on each API client in the Laces app (**Permissions** when you
create or edit a key). A token carries the scopes it asked for, intersected
with what the client holds **now**, so removing a scope in the app takes effect
on existing tokens on their next request. A scope you add applies to tokens
issued afterwards: fetch a new token to use it.

| Scope | In the app | Allows | Default | Publishable key |
| - | - | - | - | - |
| `events:read` | Read events | [List events](/api-reference/v1/events/list), [get an event](/api-reference/v1/events/get) | On | Yes |
| `checkout_sessions:write` | Start hosted checkout | [Create](/api-reference/v1/checkout-sessions/create) and [read](/api-reference/v1/checkout-sessions/get) checkout sessions | On | Create only |
| `orders:write` | Create orders | [Create an order](/api-reference/v1/orders/create), [pay an order](/api-reference/v1/orders/pay) | On | **Never** |
| `orders:read` | Read orders | [List orders](/api-reference/v1/orders/list), [get an order](/api-reference/v1/orders/get) | **Off** | **Never** |

A route called without the scope it needs answers
`403 insufficient_scope`.

## `orders:read` returns personal data

<Warning>
  `orders:read` exposes **every order in your organization**, including the
  buyer's name, email and phone number, whether or not your integration created
  the order. It is off by default, and the app warns you when you turn it on.

  Enable it only on a client whose server genuinely needs it, and treat that
  client secret like a database password.
</Warning>

You don't need `orders:read` to learn whether a payment succeeded:

* **Webhooks** tell you, and never include buyer details.
* **Checkout session reads** (`checkout_sessions:write`) tell you the linked
  order's status for hosted and embedded checkout.

`orders:read` is what you need to *poll* an order over the API.

## Requesting fewer scopes

A token can ask for less than its client holds, with the space-separated
`scope` parameter on the [token endpoint](/api-reference/v1/oauth/token).
Omit it to get everything the client holds. Asking for a scope the client
doesn't hold is `400 invalid_scope`.

```bash theme={null}
curl -s -X POST "$BASE/oauth/token" \
  -u "$LACES_CLIENT_ID:$LACES_CLIENT_SECRET" \
  -d "grant_type=client_credentials" \
  -d "scope=events:read checkout_sessions:write"
```

## The publishable key is capped

Whatever the client holds, a publishable key can only ever use
`events:read` and `checkout_sessions:write`, and only to **create** a session.
It can never create or pay orders or read them. That is what makes it safe to
put in page source. Calling an order route with it is
`403 credential_not_permitted`.


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