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 Locationhttps://api.us1.plainid.iohttps://api.ca1.plainid.iohttps://api.eu1.plainid.ioUsing 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.
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
The Environment ID can be found under the Details Tab in the Environment Settings.
The ID of the Policy to update.
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.
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.
type: boolean default: false
"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""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""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"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.
How the Platform handles the Building Block:
The 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.
Body format
Use 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.
The 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.
Condition Date Time Building Blocks
Add 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
The full updated Policy
"# 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"Bad Request
{
"errors": [
{
"code": "PAC-025",
"id": "EAB3LK",
"status": 400,
"name": "MissingBuildingBlockInput",
"message": "Request must include bbName, a building block payload, or both"
}
]
}{
"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"
}
]
}{
"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`."
}
]
}{
"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"
}
]
}Unauthorized
Forbidden
Not Found
{
"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"
}
]
}{
"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]"
}
]
}Conflict
{
"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"
}
]
}