# IP allow-list

> Calls that write must come from the addresses you registered. Reads and token requests work from any address.

Source: https://docs.stxapp.io/oauth/ip-allow-list/

> **Availability.** Available on US demo now. Live access is coming soon in the US and Ontario. See [Environments](https://docs.stxapp.io/environments/).

An app with a write scope (`orders.write`, `markets.write`) registers the IP addresses it writes from, as CIDR blocks. The rule is:

- **Calls that write must come from a registered address.** Placing or cancelling orders and creating markets from any other address are refused with `403 ip_not_allowed`, whatever the token.
- **Everything else works from any address.** Markets, events, balances, positions, order and trade history and the live feeds are served wherever the call comes from, even when the token carries a write scope. So are token requests: code exchange, refresh and `client_credentials`.

A token is not tied to the address that requested it. The check is made on each call, so a token requested anywhere writes from a registered address and only reads from any other.

## A refused write

| Transport | A write from an unregistered address |
| --- | --- |
| REST | `403` with `{"error": "ip_not_allowed", "error_description": "this app does not allow writes from this IP address"}` |
| WebSocket | The connection is accepted and read topics join. A join that needs a write scope (joining `orders:{user_id}` with `cancel_on_disconnect`, and the [combo negotiation](/websockets/channels/combo-negotiation/) topics) is refused with the join error `ip_not_allowed` |

So one app can serve both sides: read from your app servers, edge workers or a developer laptop, and keep trading and market creation on the servers you registered. Trading from your own machine? Add your public IP while you develop.

Handle `403 ip_not_allowed` separately from `403 insufficient_scope`: send writes from a registered address.
