---
title: "Set policies"
method: POST
path: "/v2/gateway.setPolicies"
tags: ["gateway"]
---

# Set policies

`POST /v2/gateway.setPolicies`

Replace an environment's gateway policies in a single atomic request.
Policies run at the edge before requests reach your app: verify API keys,
rate limit, block requests outright, or validate them against your
OpenAPI spec.

Policies are an ordered list: the gateway evaluates them top to bottom
and the first rejection short-circuits the request.

Each policy sets exactly one of `keyauth`, `ratelimit`, `firewall` or
`openapi`, plus optional `match` expressions restricting which requests
it applies to.

Every call is a full replace: the environment's policies become exactly
the request list in the given order, and the server generates a fresh id
for each one. An empty list removes all policies. The operation is
atomic: if any policy is invalid, nothing is written.

**Required Permissions**

Your root key must have one of the following permissions:
- `environment.*.set_policies` (for any environment)
- `environment.<environment_id>.set_policies` (for a specific environment)

## Request body

- V2GatewaySetPoliciesRequestBody
  - `project` string, required — Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
  - `app` string, required — Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
  - `environment` string, required — Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
  - `policies` Policy[], required — The environment's complete policy list, in evaluation order. Every call replaces all stored policies with exactly this list; an empty list removes every policy. The operation is atomic: if any policy is invalid, nothing is written. An environment can hold at most 50 policies.
    - `name` string, required — Human-readable name shown in the dashboard.
    - `enabled` boolean, required — Disabled policies are stored but skipped during evaluation.
    - `match` MatchExpr[] — Optional request matchers. The policy applies only to requests matching all expressions; omit to apply to every request.
      - `path` PathMatch — Matches on the request path.
        - `path` StringMatch, required — String matcher. Exactly one of `exact`, `prefix` or `regex` must be set.
          - `exact` string — Matches when the input equals this value.
          - `prefix` string — Matches when the input starts with this value.
          - `regex` string — Matches when the input satisfies this RE2 regular expression. Invalid patterns are rejected when the policy is created.
          - `ignoreCase` boolean — Compare case-insensitively. May accompany any match mode.
      - `method` MethodMatch — Matches when the request method is one of the listed methods.
        - `methods` string[], required
      - `header` FieldMatch — Matches a named request field (header or query parameter). Exactly one of `present` or `value` must be set.
        - `name` string, required
        - `present` true — Matches when the field is present, regardless of value.
        - `value` StringMatch — String matcher. Exactly one of `exact`, `prefix` or `regex` must be set.
          - `exact` string — Matches when the input equals this value.
          - `prefix` string — Matches when the input starts with this value.
          - `regex` string — Matches when the input satisfies this RE2 regular expression. Invalid patterns are rejected when the policy is created.
          - `ignoreCase` boolean — Compare case-insensitively. May accompany any match mode.
      - `queryParam` FieldMatch — Matches a named request field (header or query parameter). Exactly one of `present` or `value` must be set.
        - `name` string, required
        - `present` true — Matches when the field is present, regardless of value.
        - `value` StringMatch — String matcher. Exactly one of `exact`, `prefix` or `regex` must be set.
          - `exact` string — Matches when the input equals this value.
          - `prefix` string — Matches when the input starts with this value.
          - `regex` string — Matches when the input satisfies this RE2 regular expression. Invalid patterns are rejected when the policy is created.
          - `ignoreCase` boolean — Compare case-insensitively. May accompany any match mode.
    - `keyauth` KeyauthPolicy — Verifies Unkey API keys on matching requests.
      - `keyspaces` string[], required — Keyspaces to verify keys against, referenced by id. All keyspaces must belong to your workspace.
      - `locations` KeyLocation[] — Where to look for the key on incoming requests, tried in order. Defaults to the `Authorization Bearer` header when omitted.
        - `bearer` BearerTokenLocation — Extract the key from the `Authorization Bearer` header.
        - `header` HeaderKeyLocation — Extract the key from a custom header.
          - `name` string, required
          - `stripPrefix` string — Optional prefix removed from the header value before verification.
        - `queryParam` QueryParamKeyLocation — Extract the key from a query parameter.
          - `name` string, required
      - `permissionQuery` string — Optional permission query the verified key must satisfy, e.g. `documents.read AND documents.write`.
      - `ratelimits` KeyRatelimit[] — Rate limits applied during key verification.
        - `name` string, required — Name of a rate limit configured on the key or its identity, or the name of the inline override defined by `limit` and `duration`.
        - `limit` integer — Inline override: maximum number of operations per window. Must be set together with `duration`.
        - `duration` integer — Inline override: window duration in milliseconds. Must be set together with `limit`.
        - `cost` integer — Cost charged against the limit per request. Defaults to 1.
      - `credits` integer — Usage credits a matching request deducts from the verified key. Defaults to 1. Set to 0 to verify the key without spending credits, or to a higher value to charge more per request. Keys with unlimited usage are unaffected.
    - `ratelimit` RatelimitPolicy — Rate limits matching requests. Set `identifiers` with 1 to 5 sources. The deprecated `identifier` field is accepted in place of a one-entry `identifiers` list; set exactly one of the two.
      - `limit` integer, required — Maximum number of requests per window.
      - `windowMs` integer, required — Window duration in milliseconds.
      - `identifier` RatelimitIdentifier — How requests are grouped for rate limiting. Exactly one of `remoteIp`, `header`, `authenticatedSubject`, `path` or `principalField` must be set.
        - `remoteIp` RemoteIpKey — Rate limit by the client's IP address.
        - `header` HeaderKey — Rate limit by the value of a request header.
          - `name` string, required
        - `authenticatedSubject` AuthenticatedSubjectKey — Rate limit by the authenticated subject (e.g. the verified key).
        - `path` PathKey — Rate limit by the request path.
        - `principalField` PrincipalFieldKey — Rate limit by a field extracted from the authenticated principal.
          - `path` string, required
      - `identifiers` RatelimitIdentifier[] — Ordered list of sources that form a compound rate limit key. The gateway resolves each source for each request. Each unique combination of resolved values has its own counter. All counters use the same limit and window. Example: `[authenticatedSubject, path]` limits each subject separately on each path.
        - `remoteIp` RemoteIpKey — Rate limit by the client's IP address.
        - `header` HeaderKey — Rate limit by the value of a request header.
          - `name` string, required
        - `authenticatedSubject` AuthenticatedSubjectKey — Rate limit by the authenticated subject (e.g. the verified key).
        - `path` PathKey — Rate limit by the request path.
        - `principalField` PrincipalFieldKey — Rate limit by a field extracted from the authenticated principal.
          - `path` string, required
    - `firewall` FirewallPolicy — Blocks matching requests.
      - `action` 'ACTION_DENY', required — What to do with matching requests.
    - `openapi` OpenapiPolicy — Validates matching requests against the app's uploaded OpenAPI spec. Has no configuration of its own. If no spec has been uploaded for the deployment, the policy is a no-op and requests pass through unvalidated.

## Response `200`

Successfully set the policies.

- V2GatewaySetPoliciesResponseBody
  - `meta` Meta, required — Metadata object included in every API response. This provides context about the request and is essential for debugging, audit trails, and support inquiries. The `requestId` is particularly important when troubleshooting issues with the Unkey support team.
    - `requestId` string, required — A unique id for this request. Always include this ID when contacting support about a specific API request. This identifier allows Unkey's support team to trace the exact request through logs and diagnostic systems to provide faster assistance.
  - `data` EmptyResponse, required — Empty response object by design. A successful response indicates this operation was successfully executed.

## Other responses

- `400` — Bad request
- `401` — Unauthorized
- `403` — Forbidden - Insufficient permissions (requires `environment.*.set_policies`)
- `404` — Not Found - The environment or a referenced keyspace does not exist in your workspace
- `429` — Too Many Requests
- `500` — Internal server error

---

[API](https://skmtc.net/unkeyed/apis/unkey-api.md) · [All operations](https://skmtc.net/unkeyed/apis/unkey-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/unkeyed/unkey-api/revisions/a021527e00d2/schema)
