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

# Allowed Origins

> Restrict your Storefront API token to specific domains

Your Storefront API token is **public by default** — anyone who has it can use it from any website. To limit which domains can call the Storefront API with your token, manage the **Allowed Origins** list in your OpenBridge dashboard.

## Why restrict origins?

Storefront tokens are designed to be embedded in client-side code, so they're inherently visible to anyone viewing your site. That's normally fine — but if a token is scraped and reused on a different site, you may want to block it.

Restricting origins gives you:

* **Domain-level access control** — only your own sites can use the token
* **Wildcard support** — `*.example.com` covers every subdomain
* **Local development** — `localhost` works out of the box

## Manage origins

Open the dashboard:

<Card title="Dashboard → Origins" icon="globe" href="https://openbridge.shop/dashboard/origins">
  Add, remove, and toggle origin restrictions
</Card>

You can also reach this from the **Manage Allowed Origins** button on the OpenBridge embedded Shopify app.

## How it works

OpenBridge inspects the `Origin` header on every incoming Storefront API request. When restrict mode is on, the request is matched against your allowed list.

### Restrict mode

* **Off** (default): every origin can use the token.
* **On**: only origins on your list can use the token. Requests from other origins return `403 Forbidden`.

### Origin formats

| Format | Example | Matches |
| - | - | - |
| Exact host | `shop.example.com` | Only `shop.example.com` |
| Wildcard subdomain | `*.example.com` | `www.example.com`, `shop.example.com`, etc. |
| Localhost | `localhost` | Local development |
| With port | `localhost:3000` | A specific local port |

<Note>
  Origins are normalized to lowercase, without protocol (`https://`) or trailing slashes. `HTTPS://Example.com/` becomes `example.com`.
</Note>

### Limits

* Up to **10 origins** per shop.
* Origins are matched against the `Origin` header sent by the browser — server-side calls without an Origin header still go through when restrict mode is off.

## Common patterns

**Production site only**

```
example.com
www.example.com
```

**Production + staging + local dev**

```
example.com
www.example.com
*.staging.example.com
localhost
localhost:3000
```

**Multi-tenant SaaS**

```
*.app.example.com
example.com
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="My requests started returning 403">
    Restrict mode is on and the request's `Origin` doesn't match any entry on your list. Add the origin in the dashboard, or temporarily turn off restrict mode while you debug.
  </Accordion>

  <Accordion title="Wildcards aren't matching">
    Wildcards only work as the **leftmost label**. `*.example.com` is valid; `shop.*.com` is not.
  </Accordion>

  <Accordion title="Server-side requests work even with restrict on">
    Restriction is based on the `Origin` header, which only browsers attach. A `curl` or backend request typically has no `Origin` and is allowed through. Use admin-side authentication if you need to block server-side use.
  </Accordion>
</AccordionGroup>


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