CORS & origins
The origin allowlist, why embed keys demand an Origin, and how to debug a 403.
Every project carries an allowlist of browser origins. It is what makes an embed key safe to publish: the key is public, but it only works from somewhere you named.
The rules, by key kind
| Key kind | No Origin header | Origin present | Empty allowlist |
|---|---|---|---|
| Embed | 403. There is no server-side fallback. | Must be on the allowlist. | Rejects everything. |
| Integration | Allowed — this is the server-to-server case. | Must be on the allowlist. | Rejects every browser origin. |
Matching is exact
- Scheme, host, and port all count:
https://example.comdoes not coverhttp://example.comorhttps://www.example.com. - There are no wildcards. List each origin you serve from.
- Local development needs its own entry, e.g.
http://localhost:5173.
Debugging a 403
| Message | Cause |
|---|---|
Embed keys require a browser Origin header | An embed key was used from a server, or from a client that stripped the Origin header. Use an integration key for server-to-server calls. |
Origin not allowed for this project | The request's Origin is not on the project's allowlist. Add it in the dashboard under the project's settings. |
IP address not allowed for this project | The project has an IP allowlist and the caller's address is not on it. Checked before the request body is even parsed. |
Preflight is handled for you: OPTIONS on any /v1/ path returns 204 before authentication runs, so a preflight never fails for a credential reason.
Ready to ship?
Get started free