> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plainid.io/llms.txt
> Use this file to discover all available pages before exploring further.
# Update Policy Building Block
> This API call updates, adds, replaces, or removes a single Policy Building Block, without sending the full Policy code.
Notice
Accessing the Policy
Management APIs is through a dedicated domain/URL, according to your
PlainID Tenant LocationUnited States (US) -
`https://api.us1.plainid.io`Canada (CA) -
`https://api.ca1.plainid.io`Europe (EU) -
`https://api.eu1.plainid.io`
Using HTML Encoded Special Characters
Use HTML encoded patterns when working with values that contain special characters like spaces, dashes, etc. Refer to this HTML URL Encoding Reference for a full list.
Important note about headers
Refer to the headers below to modify your cURL sample. Check if the following headers are in the sample, if not, ensure you add it to your cURL sample before pasting into your API tool.
Headers
*Required
| Header |
Value |
cURL Line |
| Accept |
`text/plain;language=rego` |
`-H "Accept:text/plain;language=rego"` |
| Content-Type |
`text/plain;language=rego` |
`-H "Content-Type:text/plain;language=rego"` |
cURL Sample Guidelines
In order for the relevant parameters to appear in the cURL sample, you can input the values in the interactive API console on the right in the Try It or Code Sample tabs. You can then copy the cURL sample from the Code Sample tab in the correct format.
## OpenAPI
````json POST /api/2.0/policies/{envId}/{policyId}/building-blocks
{
"openapi": "3.0.3",
"info": {
"title": "Management APIs",
"version": "1.0.0",
"contact": {
"name": "PlainID",
"url": "https://plainid.com",
"email": "contact@plainid.com"
},
"license": {
"name": "Commercial",
"url": "https://plainid.com/license"
},
"termsOfService": "https://www.plainid.com/terms/",
"description": "The PlainID Authorization Platform provides Management capabilities through the APIs below.
To access the Management APIs, make sure to enter your dedicated domain according to your PlainID Tenant Location:
| Region | Base URL |
|---|
| United States (US) | https://api.us1.plainid.io |
| Canada (CA) | https://api.ca1.plainid.io |
| Europe (EU) | https://api.eu1.plainid.io |
| Local PAA | https://api.plainid.local |
"
},
"servers": [
{
"description": "United States",
"url": "https://api.us1.plainid.io"
},
{
"description": "Europe",
"url": "https://api.eu1.plainid.io"
},
{
"description": "Canada",
"url": "https://api.ca1.plainid.io"
},
{
"description": "Local PAA",
"url": "https://api.plainid.local"
}
],
"tags": [
{
"name": "access-file-authorizer-oas",
"description": "access-file-authorizer-oas"
},
{
"name": "authz-packager-oas",
"description": "authz-packager-oas"
},
{
"name": "SQL Database Authorizer",
"description": "API for modifying SQL queries based on authorization policies"
},
{
"name": "delegated-admin-oas",
"description": "delegated-admin-oas"
},
{
"name": "Discovery",
"description": "Discovery APIs"
},
{
"name": "Enrichment",
"description": "Enrichment APIs"
},
{
"name": "env-mgmt-oas",
"description": "env-mgmt-oas"
},
{
"name": "hybrid-commander-oas",
"description": "hybrid-commander-oas"
},
{
"name": "auth-keys",
"description": "Auth key operations"
},
{
"name": "components",
"description": "Component operations"
},
{
"name": "paas",
"description": "PAA operations"
},
{
"name": "paa-groups",
"description": "PAA group operations"
},
{
"name": "packages",
"description": "Package configuration operations"
},
{
"name": "secret-stores",
"description": "Secret store operations"
},
{
"name": "Table Mapping",
"description": "Table Mapping"
},
{
"name": "Column Mapping",
"description": "Column Mapping"
},
{
"name": "Api Mapping",
"description": "Api Mapping"
},
{
"name": "Asset Type Ruleset",
"description": "Asset Type Ruleset"
},
{
"name": "Business Entity Ruleset",
"description": "Business Entity Ruleset"
},
{
"name": "notifier-oas",
"description": "notifier-oas"
},
{
"name": "shadow-tracker",
"description": "Shadow tracker SSE stream"
},
{
"name": "orchestrator-oas",
"description": "orchestrator-oas"
},
{
"name": "POP",
"description": "pop operations"
},
{
"name": "org-mgmt-oas",
"description": "org-mgmt-oas"
},
{
"name": "pip-mgmt-oas",
"description": "pip-mgmt-oas"
},
{
"name": "monitor-loggers",
"description": "monitor-loggers"
},
{
"name": "Policy Management APIs",
"description": "Policy Management APIs"
},
{
"name": "Conditions",
"description": "Conditions."
},
{
"name": "Dynamic Groups",
"description": "Dynamic groups."
},
{
"name": "Policy Management APIs 1.0",
"description": "Policy Management APIs 1.0"
},
{
"name": "Policy Management APIs 2.0",
"description": "Policy Management APIs 2.0"
},
{
"name": "Policy Building Blocks Management APIs 2.0",
"description": "Policy Building Blocks Management APIs 2.0"
},
{
"name": "Audit",
"description": "Audit"
},
{
"name": "Asset Template",
"description": "Asset Template"
},
{
"name": "Application",
"description": "Application"
},
{
"name": "Api Mapper",
"description": "Api Mapper"
},
{
"name": "Identity Template",
"description": "Identity Template"
},
{
"name": "Identity Sources",
"description": "Identity Sources"
},
{
"name": "Mapper Sets",
"description": "Mapper Sets"
},
{
"name": "Identity Template V2",
"description": "Identity Template V2"
},
{
"name": "PAA Sources",
"description": "PAA Sources"
},
{
"name": "PAA Views",
"description": "PAA Views"
},
{
"name": "PAA Groups",
"description": "PAA Groups"
},
{
"name": "Scope",
"description": "Managed Scope APIs"
},
{
"name": "Authentication for Management APIs",
"description": "Authentication for Management APIs"
},
{
"name": "runtime",
"description": "runtime"
},
{
"name": "Cache Management",
"description": "Cache invalidation operations for Runtime service"
},
{
"name": "AuthZen",
"description": "AuthZen Authorization API 1.0 proxy (https://openid.net/specs/authorization-api-1_0.html). Authenticate with a bearer token, or with a `clientId`/`clientSecret` pair sent as the `X-Client-Id` and `X-Client-Secret` headers, or as `clientId`/`clientSecret` fields in the request body."
}
],
"externalDocs": {
"url": "https://docs.plainid.io/apidocs/policy-management-apis"
},
"paths": {
"/api/2.0/policies/{envId}/{policyId}/building-blocks": {
"post": {
"tags": [
"Policy Management APIs 2.0"
],
"summary": "Update Policy Building Block",
"description": "This API call updates, adds, replaces, or removes a single Policy Building Block, without sending the full Policy code.\n\n\n
Notice
Accessing the Policy\nManagement APIs is through a dedicated domain/URL, according to your\nPlainID Tenant LocationUnited States (US) -\n`https://api.us1.plainid.io`Canada (CA) -\n`https://api.ca1.plainid.io`Europe (EU) -\n`https://api.eu1.plainid.io`
\n\nUsing HTML Encoded Special Characters
\nUse HTML encoded patterns when working with values that contain special characters like spaces, dashes, etc. Refer to this HTML URL Encoding Reference for a full list.
\nImportant note about headers
\nRefer to the headers below to modify your cURL sample. Check if the following headers are in the sample, if not, ensure you add it to your cURL sample before pasting into your API tool.
\nHeaders
\n*Required\n\n\n| Header | \nValue | \ncURL Line | \n
\n\n\n| Accept | \n`text/plain;language=rego` | \n`-H \"Accept:text/plain;language=rego\"` | \n
\n\n| Content-Type | \n`text/plain;language=rego` | \n`-H \"Content-Type:text/plain;language=rego\"` | \n
\n\n
\n
cURL Sample Guidelines
In order for the relevant parameters to appear in the cURL sample, you can input the values in the interactive API console on the right in the Try It or Code Sample tabs. You can then copy the cURL sample from the Code Sample tab in the correct format.
\n",
"operationId": "updatePolicyBuildingBlock",
"parameters": [
{
"in": "path",
"name": "envId",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "The Environment ID can be found under the Details Tab in the Environment Settings."
},
{
"in": "path",
"name": "policyId",
"required": true,
"schema": {
"type": "string"
},
"description": "The ID of the Policy to update."
},
{
"in": "query",
"name": "bbName",
"description": "The name of the Building Block to update, replace, or remove. The Building Block must already exist in the Policy. Required for Update, Replace, and Remove operations. Omit it for Add. Send only one `bbName`.",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "evaluateByBBName",
"description": "Set to `true` to match Building Blocks by name. If the request contains a Building Block whose logic doesn't match any existing Building Block, the Platform updates the existing Building Block with the same name instead of creating a new one.\n\ntype: boolean\ndefault: false\n"
}
],
"security": [
{
"bearerAuth": []
}
],
"requestBody": {
"required": false,
"content": {
"text/plain;language=rego": {
"schema": {
"type": "string",
"description": "Send the Rego code for one Building Block to replace that Building Block in the Policy. To remove `bbName` from the Policy, send an empty body.\n
\n**How the Platform handles the Building Block**:\n\nThe Platform processes the Building Block the same way as a full Policy import. If a Building Block with the same logic already exists in the Environment, the Platform links that Building Block to the Policy and keeps its existing name. Otherwise, the Platform creates a new Building Block and links it. When the Platform unlinks a Building Block from the Policy, the Building Block stays in the Environment.\n
\n**Body format**\n\nUse the Building Blocks Rego format: start with `package building_blocks` and `import rego.v1`, then add the full definition of **one** Building Block. For a Ruleset, include all its action sections. For other Building Blocks, include all their OR rules.\n\nThe request replaces the whole Building Block, so it removes any section you leave out. For example, if a Ruleset has `View`, `Edit`, and `Delete` sections and you send only `View`, the Ruleset keeps only `View`.\n
\n**Condition Date Time Building Blocks**\n\nAdd `import data.plainid.datetime.time_in_range` after `import rego.v1`, the same as in the Building Blocks APIs. If you leave it out, the request fails with a validation error. The Platform adds this import to the Policy when needed. Other\n"
},
"examples": {
"Update or Add a Dynamic Group": {
"value": "package building_blocks\nimport rego.v1\n\n# METADATA\n# custom:\n# plainid:\n# kind: DynamicGroup\n# name: Member customers\ndynamic_group(identity) if {\n identity.template == \"User\"\n identity[\"User_Type\"] == \"External\"\n identity[\"Membership_Type\"] == \"Gold\"\n}\n"
},
"Update a Ruleset": {
"value": "package building_blocks\nimport rego.v1\n\n# METADATA\n# custom:\n# plainid:\n# kind: Ruleset\n# name: User personal bank accounts\nruleset(asset, identity, requestParams, action) if {\n asset.template == \"Bank Accounts\"\n identity.template == \"User\"\n asset[\"account_owner\"] == identity[\"Userid_identity\"]\n action.id in [\"View\"]\n}\n"
},
"Update a Date Time Condition": {
"value": "package building_blocks\nimport rego.v1\nimport data.plainid.datetime.time_in_range\n\n# METADATA\n# custom:\n# plainid:\n# kind: Condition Date Time\n# name: Business Hours\ncondition_datetime if {\n time_in_range({\n \"months\": [\n \"JANUARY\", \"FEBRUARY\", \"MARCH\",\n \"APRIL\", \"MAY\", \"JUNE\",\n \"JULY\", \"AUGUST\", \"SEPTEMBER\",\n \"OCTOBER\", \"NOVEMBER\", \"DECEMBER\"\n ],\n \"days\": [\"MONDAY\", \"TUESDAY\", \"WEDNESDAY\", \"THURSDAY\", \"FRIDAY\"],\n \"times\": {\"from\": \"08:00\", \"to\": \"17:00\", \"timeZone\": \"America/Detroit\"},\n \"dates\": {\"from\": \"2026-01-01\", \"to\": null}\n })\n}\n"
}
}
}
}
},
"responses": {
"201": {
"description": "The full updated Policy",
"headers": {
"x-request-id": {
"schema": {
"type": "string"
}
}
},
"content": {
"text/plain;language=rego": {
"schema": {
"type": "string"
},
"examples": {
"Updated Policy": {
"value": "# METADATA\n# custom:\n# plainid:\n# policyId: 08ae32e4-fbf3-4cc8-b3b9-3b4061d1c825\n# name: Manage personal account and Credit cards\n# accessType: Allow\npackage policy\nimport rego.v1\n\n# METADATA\n# custom:\n# plainid:\n# kind: DynamicGroup\n# name: Member customers (1)\n# id: 2b5c6a8e-1f3d-4c7a-9e0b-8d4f2a6c1e93\ndynamic_group(identity) if {\n identity.template == \"User\"\n identity[\"User_Type\"] == \"External\"\n identity[\"Membership_Type\"] == \"Gold\"\n}\n"
}
}
}
}
},
"400": {
"description": "Bad Request",
"headers": {
"x-request-id": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Errors"
},
"examples": {
"Missing bbName and body": {
"value": {
"errors": [
{
"code": "PAC-025",
"id": "EAB3LK",
"status": 400,
"name": "MissingBuildingBlockInput",
"message": "Request must include bbName, a building block payload, or both"
}
]
}
},
"Ambiguous bbName": {
"value": {
"errors": [
{
"code": "PAC-027",
"args": {
"0": "Member customers",
"1": "08ae32e4-fbf3-4cc8-b3b9-3b4061d1c825"
},
"id": "EAB3LM",
"status": 400,
"name": "AmbiguousBuildingBlockName",
"message": "Policy [08ae32e4-fbf3-4cc8-b3b9-3b4061d1c825] has more than one building block named [Member customers] and it cannot be resolved from the payload. Use the Import Policy API"
}
]
}
},
"Date Time Condition without the import": {
"value": {
"errors": [
{
"code": "TV-001",
"name": "CompilationError",
"line": 10,
"message": "Internal compiler error: undefined function time_in_range"
},
{
"code": "PACV-076",
"name": "InvalidConditionDateTimeExpr",
"line": 10,
"message": "Invalid Condition Date Time rule [Business Hours]: time_in_range is used without `import data.plainid.datetime.time_in_range`. Hint: use time_in_range({\"months\": [...], \"days\": [...], \"times\": {...}, \"dates\": {...}}) with `import data.plainid.datetime.time_in_range`."
}
]
}
},
"Building Block already in the Policy": {
"value": {
"errors": [
{
"code": "PACV-084",
"name": "BuildingBlockNameConflict",
"line": 4,
"message": "Building block [Premium customers] already exists in policy [08ae32e4-fbf3-4cc8-b3b9-3b4061d1c825]. To update it, send bbName=Premium customers"
}
]
}
}
}
}
}
},
"401": {
"description": "Unauthorized",
"headers": {
"x-request-id": {
"schema": {
"type": "string"
}
}
}
},
"403": {
"description": "Forbidden",
"headers": {
"x-request-id": {
"schema": {
"type": "string"
}
}
}
},
"404": {
"description": "Not Found",
"headers": {
"x-request-id": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Errors"
},
"examples": {
"Policy not found": {
"value": {
"errors": [
{
"code": "PUA-033",
"args": {
"0": "08ae32e4-fbf3-4cc8-b3b9-3b4061d1c825",
"1": "ceef5853-1491-4d1c-ae52-2f2a1729b3a4"
},
"id": "E7WJBB",
"status": 404,
"name": "PolicyNotFoundError",
"message": "Policy Id doesn't exist in the environment"
}
]
}
},
"Building Block not in the Policy": {
"value": {
"errors": [
{
"code": "PAC-026",
"args": {
"0": "Member customers",
"1": "08ae32e4-fbf3-4cc8-b3b9-3b4061d1c825"
},
"id": "EAB3LN",
"status": 404,
"name": "BuildingBlockNotInPolicy",
"message": "Building block [Member customers] doesn't exist in policy [08ae32e4-fbf3-4cc8-b3b9-3b4061d1c825]"
}
]
}
}
}
}
}
},
"409": {
"description": "Conflict",
"headers": {
"x-request-id": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Errors"
},
"examples": {
"Policy changed during the update": {
"value": {
"errors": [
{
"code": "PAC-028",
"args": {
"0": "08ae32e4-fbf3-4cc8-b3b9-3b4061d1c825"
},
"id": "EAB3LP",
"status": 409,
"name": "PolicyConcurrentModification",
"message": "Policy [08ae32e4-fbf3-4cc8-b3b9-3b4061d1c825] was changed by another request while its building block was being updated. Nothing was changed; retry the request"
}
]
}
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Errors": {
"type": "object",
"properties": {
"errors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"Error": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"id": {
"type": "string"
},
"status": {
"type": "integer"
},
"name": {
"type": "string"
},
"message": {
"type": "string"
},
"args": {
"type": "object",
"properties": {
"path": {
"type": "string"
}
}
}
}
}
},
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"description": " For more details about Administration API Authentication, check out the Authentication APIs documentation
Provide your bearer token in the Authorization header when making requests to protected resources.
Example: `Authorization: Bearer 123`"
}
}
}
}
````