---
title: "Declare a policy rule for a project"
method: POST
path: "/projects/{project_id}/policy-rules"
tags: ["Policy"]
---

# Declare a policy rule for a project

`POST /projects/{project_id}/policy-rules`

## Request

- Base URL: `https://adslighthouse.com/api/v1`
- URL: `https://adslighthouse.com/api/v1/projects/{project_id}/policy-rules`
- Auth: HTTP bearer

Creates a policy rule, exactly like Settings > Policy rules. Rules encode your team's monitoring criteria; a match is a lead for review, not proof of a policy violation. From the next saved check on, each ad that breaks it opens or updates a case (one per rule and advertiser, plus the affiliate ID for affiliate rules). Earlier checks are not evaluated automatically: preview with preview_policy_rule first. Types and params: forbidden_terms {terms, fields: headline|description|display_url, applies_to, authorized_domains}; brand_term {extra_terms, authorized_domains}; direct_linking {authorized_domains}; promo_code {codes, any_explicit_code, allowed_codes, applies_to, authorized_domains}; position_limit {top_positions 1-10, applies_to, authorized_domains}; affiliate_id {authorized_ids}. applies_to is unauthorized (default for position limits) or all_non_owned (default for terms and codes). Your own domains never match, except for affiliate_id; advertisers classified as authorized retailers and authorized_domains count as authorized. A match is a lead to review: an observation shows an ad was displayed for a search at a moment, not proof of a violation, spend or a purchased keyword. Requires the write scope and an idempotency key; a retry with the same key returns the same rule.

## Path parameters

- `project_id` string, required: The project: its id, its brand domain (for example nike.example) or its exact project or brand name. Unknown or ambiguous references return not_found; call list_projects then.

## Headers

- `Idempotency-Key` string, required: A unique value you choose for this request, such as a UUID. Repeating the same key returns the first result instead of starting paid work again.

## Request body

- object
  - `name` string, required: A name your team recognizes, up to 120 characters.
  - `enabled` boolean: false saves the rule paused. Defaults to true.
  - `type` 'forbidden_terms' | 'brand_term' | 'direct_linking' | 'promo_code' | 'position_limit' | 'affiliate_id', required
  - `params` object: Parameters for the rule type; send only the ones that type uses.
    - `terms` string[]: Forbidden words or phrases.
    - `fields` string[]: Ad parts to check for terms.
    - `applies_to` 'unauthorized' | 'all_non_owned'
    - `authorized_domains` string[]
    - `extra_terms` string[]: Extra brand terms.
    - `codes` string[]: Forbidden promo codes.
    - `any_explicit_code` boolean: Also flag any other code written after the word code.
    - `allowed_codes` string[]
    - `top_positions` integer
    - `authorized_ids` string[]
  - `scope` object: Observations to check: engine, device, os, country and location, each one value or a list. Omit for every observation.
    - `engine` union: Search engine, or a list of engines combined with OR.
      - 'google' | 'bing'
      - string[]
    - `device` union: Device, or a list combined with OR.
      - 'desktop' | 'mobile'
      - string[]
    - `os` union: Operating system. unspecified matches checks that did not pin one. Must fit the chosen device.
      - 'windows' | 'macos' | 'android' | 'ios' | 'unspecified'
      - string[]
    - `country` union: ISO 3166-1 alpha-2 country code such as US, or a list.
      - string
      - string[]
    - `location` union: Saved location key: code:<location code>, name:<label> or country:<ISO code>. get_project_details lists the keys that have data.
      - string
      - string[]

## Response `201`

Declare a policy rule for a project

- object
  - `created` boolean, required
  - `rule` object, required
    - `id` string, required
    - `project_id` string, required
    - `name` string, required
    - `type` 'forbidden_terms' | 'brand_term' | 'direct_linking' | 'promo_code' | 'position_limit' | 'affiliate_id', required
    - `enabled` boolean, required
    - `readable` boolean, required: False when the stored configuration no longer parses; such a rule is skipped.
    - `params` object, nullable, required: Parameters for the rule type; send only the ones that type uses.
      - `terms` string[]: Forbidden words or phrases.
      - `fields` string[]: Ad parts to check for terms.
      - `applies_to` 'unauthorized' | 'all_non_owned'
      - `authorized_domains` string[]
      - `extra_terms` string[]: Extra brand terms.
      - `codes` string[]: Forbidden promo codes.
      - `any_explicit_code` boolean: Also flag any other code written after the word code.
      - `allowed_codes` string[]
      - `top_positions` integer
      - `authorized_ids` string[]
    - `scope` object, nullable, required: Which observations the rule checks. null in a dimension means every value; values within a dimension combine with OR, dimensions with AND.
      - `engine` string[], nullable, required
      - `device` string[], nullable, required
      - `os` string[], nullable, required
      - `country` string[], nullable, required
      - `location` string[], nullable, required
    - `open_cases` integer, required
    - `created_at` string, required
    - `updated_at` string, required
  - `request_id` string

## Other responses

- `400`: Invalid parameters, cursor or body.
- `401`: Missing, invalid, expired or revoked credential.
- `403`: The credential lacks the write scope, the plan does not include the API, or the allowance is used up.
- `404`: Unknown project, keyword or run in this account.
- `409`: The idempotency key was already used for a different request.
- `429`: Rate limit reached. Retry after the Retry-After seconds.
- `503`: The requested service or file is temporarily unavailable.

---

[API](https://skmtc.dev/adslighthouse/apis/ads-lighthouse-api.md) · [All operations](https://skmtc.dev/adslighthouse/apis/ads-lighthouse-api/llms.txt) · [OpenAPI document](https://skmtc.dev/adslighthouse/apis/ads-lighthouse-api/revisions/e1a4a40b11a9?raw)
