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

# Add Policy

> Adds a new policy to an API Proxy. The policy can be added to the request, response, or error pipeline, and can apply to all endpoints or a specific endpoint.

## Endpoint

```plaintext theme={null}
POST /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
```

## Authentication

Requires a Personal API Access Token.

### Header

```plaintext theme={null}
Authorization: Bearer YOUR_TOKEN
```

## Request

### Headers

| Header        | Value            | Required |
| ------------- | ---------------- | -------- |
| Authorization | Bearer {token}   | Yes      |
| Content-Type  | application/json | Yes      |

### Path Parameters

| Parameter    | Type   | Required | Description                                       |
| ------------ | ------ | -------- | ------------------------------------------------- |
| projectName  | string | Yes      | Project name                                      |
| apiProxyName | string | Yes      | API Proxy name                                    |
| policyName   | string | Yes      | Policy name (must be unique within the API Proxy) |

### Request Body

#### Full JSON Body Example

```json theme={null}
{
  "operationMetadata": {
    "targetScope": "ALL",
    "targetPipeline": "REQUEST",
    "deploy": true,
    "deployTargetEnvironmentNameList": ["production"],
    "order": 1
  },
  "policy": {
    "type": "policy-api-based-throttling",
    "description": "API throttling policy - 100 requests per minute",
    "active": true,
    "targetVariableForIdentity": {
      "type": "HEADER",
      "headerName": "X-API-Key"
    },
    "messageCountForInterval": 100,
    "throttlingInterval": "ONE_MINUTE",
    "intervalPeriodLength": 1,
    "intervalWindowType": "FIXED",
    "cacheConnectionTimeoutInSeconds": 3,
    "cacheErrorHandlingType": "FAIL",
    "showRateLimitStatisticsInResponseHeader": true,
    "detailList": [
      {
        "targetValue": "VIP",
        "regexExpression": false,
        "messageCountForInterval": 1000,
        "intervalPeriodLength": 1,
        "quotaInterval": "ONE_MINUTE"
      }
    ],
    "policyCondition": {
      "conditionRuleList": [
        {
          "conditionCriteria": "VALUE",
          "firstVariable": {
            "name": "userTypeHeader",
            "type": "HEADER",
            "headerName": "X-User-Type"
          },
          "variableDataType": "STRING",
          "valueComparisonOperator": "EQ",
          "secondValueSource": "VALUE",
          "secondValue": "PREMIUM"
        }
      ]
    }
  }
}
```

#### Request Body Fields

##### Policy Operation Metadata

| Field                           | Type    | Required | Default | Description                                                                                 |
| ------------------------------- | ------- | -------- | ------- | ------------------------------------------------------------------------------------------- |
| targetScope                     | string  | Yes      | -       | Policy scope: `ALL` or `ENDPOINT`                                                           |
| targetEndpoint                  | string  | No\*     | -       | Endpoint path (required if targetScope=ENDPOINT)                                            |
| targetEndpointHTTPMethod        | string  | No\*     | -       | HTTP method (required if targetScope=ENDPOINT)                                              |
| targetPipeline                  | string  | Yes      | -       | Pipeline: `REQUEST`, `RESPONSE`, or `ERROR`                                                 |
| deploy                          | boolean | No       | true    | Whether to deploy after adding policy                                                       |
| deployTargetEnvironmentNameList | array   | No       | \[]     | List of environment names to deploy to                                                      |
| order                           | integer | No       | null    | Policy execution order (starts from 1). If null or >= list size, policy is added at the end |

### EnumPolicyTargetScope

* `ALL` - Policy applies to all endpoints
* `ENDPOINT` - Policy applies only to specified endpoint

### EnumPolicyTargetPipeline

* `REQUEST` - Executes in request pipeline
* `RESPONSE` - Executes in response pipeline
* `ERROR` - Executes in error pipeline

### EnumHttpRequestMethod

* `GET` - GET method
* `POST` - POST method
* `PUT` - PUT method
* `DELETE` - DELETE method
* `PATCH` - PATCH method
* `OPTIONS` - OPTIONS method
* `HEAD` - HEAD method
* `TRACE` - TRACE method
* `ALL` - All methods

**Note:** When `targetScope` is `ENDPOINT`, both `targetEndpoint` and `targetEndpointHTTPMethod` are required.

##### policy

The policy object structure varies by policy type. All policies share common base fields:

###### Common Policy Fields

| Field            | Type    | Required | Default | Description                                                         |
| ---------------- | ------- | -------- | ------- | ------------------------------------------------------------------- |
| type             | string  | Yes      | -       | Policy type (discriminator field)                                   |
| description      | string  | No       | -       | Policy description                                                  |
| active           | boolean | No       | true    | Whether policy is active                                            |
| policyCondition  | object  | No       | -       | Policy condition configuration (see PolicyCondition below)          |
| errorMessageList | array   | No       | -       | Custom error messages (if not provided, standard messages are used) |

**Note:** The `name` field is not included in the request body. The policy name is taken from the path parameter `{policyName}`.

###### Policy Types

Each policy type has its own specific fields. See individual policy documentation pages for details:

* [API Based Throttling](/api-reference/policies/policies/policy-api-based-throttling)
* [Blocked IP List](/api-reference/policies/policies/policy-black-ip)
* [Allowed IP List](/api-reference/policies/policies/policy-white-ip)
* [Authentication Basic](/api-reference/policies/policies/policy-auth-basic)
* … (see [Policies Index](/api-reference/policies/crud/add-policy.mdx) for complete list)

###### Policy Condition (PolicyConditionDTO)

| Field             | Type  | Required | Default | Description                                                      |
| ----------------- | ----- | -------- | ------- | ---------------------------------------------------------------- |
| conditionRuleList | array | No       | \[]     | List of condition rules. If empty, default AND condition is used |

**Note:** If `conditionRuleList` is empty or not provided, a default AND condition is created.

###### conditionRuleList Item (ConditionRuleDTO)

| Field                   | Type   | Required | Default | Description                                                             |
| ----------------------- | ------ | -------- | ------- | ----------------------------------------------------------------------- |
| conditionRuleList       | array  | No       | \[]     | Nested condition rules (for complex conditions)                         |
| conditionCriteria       | string | Yes      | -       | Condition criteria: `VALUE`, `NOT`, `AND`, or `OR`                      |
| firstVariable           | object | Yes      | -       | First variable for comparison (see VariableDTO below)                   |
| variableDataType        | string | Yes      | -       | Variable data type: `STRING`, `NUMBER`, `DATE`, `BOOLEAN`               |
| dateFormat              | string | No       | -       | Date format for date comparisons (required if variableDataType=DATE)    |
| valueComparisonOperator | string | Yes      | -       | Comparison operator (see EnumConditionValueComparisonOperator below)    |
| secondValueSource       | string | Yes      | -       | Second value source: `VALUE` or `VARIABLE`                              |
| secondValue             | string | No\*     | -       | Second value for comparison (required if secondValueSource=VALUE)       |
| secondVariable          | object | No\*     | -       | Second variable for comparison (required if secondValueSource=VARIABLE) |

### EnumConditionCriteria

* `VALUE` - Value comparison
* `NOT` - Negation
* `AND` - Logical AND
* `OR` - Logical OR

### EnumConditionVariableDataType

* `STRING` - String type
* `NUMERIC` - Numeric type
* `DATE` - Date type

### EnumConditionValueComparisonOperator

* `LT` - Less than
* `LE` - Less than or equal to
* `GT` - Greater than
* `GE` - Greater than or equal to
* `EQ` - Equal to
* `NE` - Not equal to
* `EQ_IGNORE_CASE` - Equal to, case insensitive (string only)
* `NE_IGNORE_CASE` - Not equal to, case insensitive (string only)
* `STARTS_WITH` - Starts with (string only)
* `NOT_STARTS_WITH` - Does not start with (string only)
* `STARTS_WITH_IGNORE_CASE` - Starts with, case insensitive (string only)
* `NOT_STARTS_WITH_IGNORE_CASE` - Does not start with, case insensitive (string only)
* `ENDS_WITH` - Ends with (string only)
* `NOT_ENDS_WITH` - Does not end with (string only)
* `ENDS_WITH_IGNORE_CASE` - Ends with, case insensitive (string only)
* `NOT_ENDS_WITH_IGNORE_CASE` - Does not end with, case insensitive (string only)
* `CONTAINS` - Contains (string only)
* `NOT_CONTAINS` - Does not contain (string only)
* `CONTAINS_IGNORE_CASE` - Contains, case insensitive (string only)
* `NOT_CONTAINS_IGNORE_CASE` - Does not contain, case insensitive (string only)
* `IS_EXISTS` - Variable exists (regardless of value)
* `IS_NOT_EXISTS` - Variable does not exist
* `IS_NOT_EMPTY` - Variable exists and is not empty
* `IS_EMPTY` - Variable does not exist or is empty
* `EXISTS_AND_EMPTY` - Variable exists but is empty
* `IN` - Value is in list
* `NOT_IN` - Value is not in list
* `IN_IGNORE_CASE` - Value is in list, case insensitive (string only)
* `NOT_IN_IGNORE_CASE` - Value is not in list, case insensitive (string only)

### EnumConditionValueSource

* `VALUE` - Compare with a constant value
* `VARIABLE` - Compare with another variable

###### firstVariable / secondVariable (VariableDTO)

| Field              | Type    | Required | Default | Description                                                               |
| ------------------ | ------- | -------- | ------- | ------------------------------------------------------------------------- |
| id                 | string  | No       | -       | Variable ID (if referencing existing variable)                            |
| projectId          | string  | No       | -       | Project ID (if referencing existing variable)                             |
| name               | string  | No\*     | -       | Variable name (required if id not provided)                               |
| description        | string  | No       | -       | Variable description                                                      |
| type               | string  | Yes      | -       | Variable type: `HEADER`, `PARAMETER`, `BODY`, `CONTEXT_VALUES`, `CUSTOM`  |
| headerName         | string  | No\*     | -       | Header name (required if type=HEADER)                                     |
| paramType          | string  | No\*     | -       | Parameter type: `QUERY`, `PATH`, `FORM` (required if type=PARAMETER)      |
| paramName          | string  | No\*     | -       | Parameter name (required if type=PARAMETER)                               |
| paramPath          | string  | No       | -       | Parameter path                                                            |
| formName           | string  | No       | -       | Form name (for form parameters)                                           |
| xpathValue         | string  | No\*     | -       | XPath value (required if type=BODY and content is XML)                    |
| jsonPathValue      | string  | No\*     | -       | JSONPath value (required if type=BODY and content is JSON)                |
| messageContentType | string  | No\*     | -       | Message content type: `JSON`, `XML`, `FORM` (required if type=BODY)       |
| contextValue       | string  | No\*     | -       | Context value (required if type=CONTEXT\_VALUES)                          |
| zoneId             | string  | No       | -       | Zone ID (for date context values)                                         |
| initWithScript     | boolean | No       | false   | Initialize with script                                                    |
| scriptLanguage     | string  | No       | -       | Script language: `GROOVY`, `JAVASCRIPT` (required if initWithScript=true) |
| scriptBody         | string  | No       | -       | Script body (required if initWithScript=true)                             |

### EnumVariableType

* `HEADER` - HTTP header
* `PARAMETER` - Query/path/form parameter
* `BODY` - Request/response body
* `CONTEXT_VALUES` - Context values (e.g., current time, IP address)
* `CUSTOM` - Custom variable (script-based)

### EnumVariableParameterType

* `QUERY` - Query parameter
* `PATH` - Path parameter
* `FORM` - Form parameter

### EnumMessageContentType

* `JSON` - JSON content
* `XML` - XML content
* `FORM` - Form content

### EnumVariableContextValue

* `CURRENT_TIME` - Current timestamp
* `CURRENT_DATE` - Current date
* `CLIENT_IP` - Client IP address
* `CLIENT_PORT` - Client port
* `SERVER_IP` - Server IP address
* `SERVER_PORT` - Server port
* `REQUEST_METHOD` - HTTP request method
* `REQUEST_URI` - Request URI
* `REQUEST_PATH` - Request path
* `REQUEST_QUERY_STRING` - Query string
* `REQUEST_PROTOCOL` - Request protocol
* `REQUEST_HOST` - Request host
* `REQUEST_SCHEME` - Request scheme
* `RESPONSE_STATUS_CODE` - Response status code
* `RESPONSE_STATUS_TEXT` - Response status text
* `API_PROXY_NAME` - API Proxy name
* `API_PROXY_ID` - API Proxy ID
* `ENDPOINT_NAME` - Endpoint name
* `ENDPOINT_ID` - Endpoint ID
* `ENVIRONMENT_NAME` - Environment name
* `ENVIRONMENT_ID` - Environment ID
* `PROJECT_NAME` - Project name
* `PROJECT_ID` - Project ID
* `USER_NAME` - User name
* `USER_ID` - User ID
* `ORGANIZATION_NAME` - Organization name
* `ORGANIZATION_ID` - Organization ID
* `ZONE_ID` - Zone ID
* `TIMEZONE_ID` - Timezone ID

### EnumScriptType

* `GROOVY` - Groovy script
* `JAVASCRIPT` - JavaScript script

## Response

### Success Response (200 OK)

```json theme={null}
{
  "status": "SUCCESS"
}
```

If `deploy: true` is set in the request, the response includes deployment result:

```json theme={null}
{
  "status": "SUCCESS",
  "deploymentResult": {
    "success": true,
    "responseTime": 1500,
    "detailList": [
      {
        "envName": "production",
        "podName": "pod-123",
        "podIp": "10.0.0.1",
        "success": true,
        "responseTime": 1500
      }
    ]
  }
}
```

#### Response Fields

| Field            | Type   | Description                                                      |
| ---------------- | ------ | ---------------------------------------------------------------- |
| status           | string | Response status: `SUCCESS` or `FAILURE`                          |
| deploymentResult | object | Deployment result (if deploy=true). See Deployment Result Object |

### Deployment Result Object (deploymentResult)

| Field        | Type    | Description                                    |
| ------------ | ------- | ---------------------------------------------- |
| success      | boolean | Overall deployment success status              |
| responseTime | integer | Total deployment response time in milliseconds |
| detailList   | array   | List of deployment details per pod/environment |

### Deployment Detail Object (detailList item)

| Field        | Type    | Description                                           |
| ------------ | ------- | ----------------------------------------------------- |
| envName      | string  | Environment name                                      |
| podName      | string  | Pod name where deployment occurred                    |
| podIp        | string  | Pod IP address                                        |
| success      | boolean | Deployment success status for this pod                |
| responseTime | integer | Deployment response time for this pod in milliseconds |

### EnumStatus

* `SUCCESS` - Operation successful
* `FAILURE` - Operation failed

### Error Response (400 Bad Request)

```json theme={null}
{
  "error": "bad_request",
  "error_description": "A policy with same name (my-policy) is already exist in API Proxy!"
}
```

#### Common Causes

* Policy name already exists
* Invalid targetScope (ENDPOINT without targetEndpoint)
* Invalid targetEndpoint (endpoint not found in API Proxy)
* Invalid policy type
* Missing required policy fields
* Invalid condition configuration

### Error Response (401 Unauthorized)

```json theme={null}
{
  "error": "unauthorized_client",
  "error_description": "Invalid token"
}
```

### Error Response (404 Not Found)

```json theme={null}
{
  "error": "not_found",
  "error_description": "ApiProxy (name: MyAPI) was not found!"
}
```

## cURL Example

### Example 1: Add Policy to All Endpoints

```bash theme={null}
curl -X POST \
  "https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/MyAPI/policies/throttling-policy/" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "operationMetadata": {
      "targetScope": "ALL",
      "targetPipeline": "REQUEST",
      "deploy": true,
      "deployTargetEnvironmentNameList": ["production"],
      "order": 1
    },
    "policy": {
      "type": "policy-api-based-throttling",
      "description": "Throttling policy",
      "active": true,
      "targetVariableForIdentity": {
        "type": "HEADER",
        "headerName": "X-API-Key"
      },
      "messageCountForInterval": 100,
      "throttlingInterval": "ONE_MINUTE",
      "intervalPeriodLength": 1,
      "intervalWindowType": "FIXED"
    }
  }'
```

### Example 2: Add Policy to Specific Endpoint

```bash theme={null}
curl -X POST \
  "https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/MyAPI/policies/endpoint-throttling/" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "operationMetadata": {
      "targetScope": "ENDPOINT",
      "targetEndpoint": "/api/users",
      "targetEndpointHTTPMethod": "GET",
      "targetPipeline": "REQUEST",
      "deploy": false,
      "order": 2
    },
    "policy": {
      "type": "policy-api-based-throttling",
      "description": "Endpoint-specific throttling",
      "active": true,
      "targetVariableForIdentity": {
        "type": "HEADER",
        "headerName": "X-API-Key"
      },
      "messageCountForInterval": 50,
      "throttlingInterval": "ONE_MINUTE",
      "intervalPeriodLength": 1,
      "intervalWindowType": "FIXED"
    }
  }'
```

### Example 3: Add Policy with Condition

```bash theme={null}
curl -X POST \
  "https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/MyAPI/policies/conditional-policy/" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "operationMetadata": {
      "targetScope": "ALL",
      "targetPipeline": "REQUEST",
      "deploy": false,
      "order": 1
    },
    "policy": {
      "type": "policy-black-ip",
      "description": "Block IPs for VIP users",
      "active": true,
      "ipList": ["192.168.1.100"],
      "policyCondition": {
        "conditionRuleList": [
          {
            "conditionCriteria": "VALUE",
            "firstVariable": {
              "name": "userTypeHeader",
              "type": "HEADER",
              "headerName": "X-User-Type"
            },
            "variableDataType": "STRING",
            "valueComparisonOperator": "EQ",
            "secondValueSource": "VALUE",
            "secondValue": "PREMIUM"
          }
        ]
      }
    }
  }'
```

## Permissions

* User must have **`API_MANAGEMENT` + `MANAGE`** permission in the project
* If `deploy: true` is set in the request, user must also have **`API_MANAGEMENT` + `DEPLOY_UNDEPLOY`** permission

## Notes and Warnings

* **Policy Name**: Policy name is taken from the path parameter, not from the request body. The `name` field in PolicyDTO is ignored (marked with @JsonIgnore).
* **Unique Names**: Policy names must be unique within the API Proxy
* **Order**: Order starts from 1. If order is null or >= current policy list size, policy is added at the end
* **Deployment**: If `deploy: true`, ensure environments exist and user has deployment permissions
* **Conditions**: If `policyCondition` is not provided, a default AND condition is created
* **Error Messages**: If `errorMessageList` is not provided, standard error messages are used
* **Endpoint Scope**: When using `targetScope: ENDPOINT`, ensure the endpoint exists in the API Proxy
* **Variable References**: Variables can be referenced by `id` (if existing) or defined inline

## Related Documentation

* [List Policies](/api-reference/policies/crud/list-policies) - List all policies
* [Update Policy](/api-reference/policies/crud/update-policy) - Update an existing policy
* [Delete Policy](/api-reference/policies/crud/delete-policy) - Delete a policy
* [Policy API Based Throttling](/api-reference/policies/policies/policy-api-based-throttling) - Example policy documentation
