---
title: "Stripe permissions"
description: "The four Stripe permissions SeatLayer needs, why each one is needed, and how to create a restricted key with exactly those scopes for test and live events."
---

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

# Stripe permissions

SeatLayer takes payments through **your own Stripe account** using a
[restricted API key](https://dashboard.stripe.com/apikeys/create) that you
paste on the dashboard's **Settings → Payments** page. A restricted key grants
only the permissions you choose, so SeatLayer never holds more access to your
account than it needs. This page lists the four permissions, says why each one
is needed, and shows how to create the key.

## The four permissions

| Permission | Level | Why SeatLayer needs it |
| --- | --- | --- |
| **Checkout Sessions** | Write · required | To open Stripe's payment page for each order. |
| **Webhook Endpoints** | Write · required | So Stripe can tell us a payment succeeded and we can confirm the seats. |
| **Refunds** | Write · recommended | To refund from your dashboard and put seats back on sale. |
| **Basic Business Contact Information** (Account) | Read · recommended | To show which Stripe account is connected and its currency. |

A key missing a **required** permission is refused when you paste it, and a
connected key that loses one shows **Connected · cannot take payments yet** on
the Payments page until it is replaced. A key missing **Refunds** still takes
payments; refunds from the dashboard fail until the scope is granted.

## Create a restricted key

1. In Stripe, open **Developers → API keys → Create restricted key**.
2. Set **Checkout Sessions**, **Refunds** and **Webhook Endpoints** to
   **Write**, and **Basic Business Contact Information** to **Read**. Leave
   every other resource on **None**.
3. Choose the mode:
- **Test events**: switch Stripe's **Test mode** toggle on and create an
     `rk_test_…` key.
- **Live events**: keep Test mode off and create an `rk_live_…` key.
   Test and live are separate keys; a test key serves sandbox events only.
4. Paste the key on **Settings → Payments**. SeatLayer verifies the
   permissions, creates its payment webhook on your account, and connects.
   Pasting a new key replaces the old one without a gap in payments.

## The permission checklist

Under a connected Stripe card the Payments page lists the four permissions
with **Granted** or **Missing** for each, from a real check against Stripe —
not from the key's prefix. A missing row shows Stripe's own message and what
it stops. **Re-check permissions** runs the check again (at most once a
minute); the page never re-checks on its own. Permissions are checked without
creating anything in your Stripe account — no session, no booking.

If Stripe rejects the key itself (it was rolled or is no longer valid) the
card reads **Stripe rejected this key — replace it**; use **Replace key** to
paste a new one.

## When the key is fine but Stripe still refuses

Sometimes the key has every permission and Stripe refuses the payment call
for a setting in your account — for example *"the product tax code is
missing"* when Stripe Tax is on without a default tax code. The card then
reads **Stripe account needs a change**, the row is marked **Refused** with
"Granted, but Stripe refused: …" and Stripe's own message, and the chip stays
*cannot take payments yet*. Fix the setting in your Stripe dashboard (for a tax message: Settings →
Tax → default product tax code), then **Re-check permissions**. Do not create
a new key for this; the key is not the problem.

SeatLayer never displays or returns your key after you paste it: it is
sealed server-side and can only be replaced, never read back.

Source: https://docs.seatlayer.io/billing/stripe-permissions/index.mdx
