Reusable compliance template API reference
Create, list, search, filter, publish, and delete reusable compliance templates through the DALP API.
A compliance template is a reusable policy pattern that an integration prepares before operators create assets. Each template stores its modules, jurisdictions, required controls, draft or published status, and module-set version.
Use these endpoints when your integration prepares policy templates before operators create assets in the Asset Designer. For the system-level module registry that templates rely on, see Compliance modules API. For the operator workflow, see Policy templates.
Template state model
Compliance templates can be DALP library templates or organisation templates. List responses include both by default. DALP library templates sort before organisation templates and are immutable through the organisation API. Your integration can read and filter them, but cannot update, publish, or delete them.
Organisation templates start as drafts and remain editable until published. Publishing changes isDraft to false. A repeat publish request returns a conflict response instead of creating a new version.
Jurisdictions are stored on the template. A template with no jurisdictions is a global template. When you filter for a specific jurisdiction, the API returns templates tagged with that jurisdiction and also includes global templates, so your integration can present jurisdiction-specific options alongside unrestricted defaults in a single list.
Endpoints
The compliance template API exposes these endpoints:
| Endpoint | Use it for |
|---|---|
GET /api/v2/settings/compliance-templates | List compliance templates in the active tenant. |
POST /api/v2/settings/compliance-templates | Create a draft compliance template. |
GET /api/v2/settings/compliance-templates/{id} | Read one compliance template. |
PUT /api/v2/settings/compliance-templates/{id} | Update a compliance template. |
PUT /api/v2/settings/compliance-templates/{id}/publish | Publish a draft template for asset creation. |
DELETE /api/v2/settings/compliance-templates/{id} | Delete a compliance template. |
Responses use the DALP single-resource or collection envelope with data and links.self. List responses also include pagination metadata. Facets are returned for isSystem, isDraft, and moduleSetVersion.
Create a draft template
Create requests start a template in draft state. If you omit moduleSetVersion, DALP uses the current module set version. Older clients may still send the deprecated legacy boolean; new code should send moduleSetVersion instead.
Legacy templates on current deployments
Most deployments keep legacy compliance templates turned off. Where that setting applies, a create request that targets the older module set is rejected before any field validation runs. The API returns DALP-0680 with a 403 status, and the rejection applies whether you send moduleSetVersion: 1 or the deprecated legacy boolean. Send moduleSetVersion: 2, or ask an operator to enable the legacy generation on an installation that still maintains older policy sets. See DALP-0680 in the error reference.
Where the older generation is turned off, list responses exclude it too, so a library you read back contains only current-generation templates.
Current-generation control IDs
Use moduleSetVersion: 2 for new templates. DALP validates every modules[].typeId and every requiredControls[] entry against that version before it saves or publishes the template. On create requests, incompatible values produce schema errors on the offending field paths, such as modules.0.typeId or requiredControls.0. The same rules apply whether the control is already configured in modules or only required for the later asset creation workflow.
| Control type ID | Category | Use it when the template should require |
|---|---|---|
address-block-list-v2 | Identity | Blocked wallet addresses. |
capital-raise-limit | Limits | A fiat-denominated capital raise window and cap. |
capped-v2 | Limits | A maximum token supply in raw token units. |
collateral-v2 | Collateral | Collateral proof claims and a configured collateral ratio. |
country-allow-list-v2 | Geographic | Recipient countries limited to allowed ISO 3166-1 numeric codes. |
country-block-list-v2 | Geographic | Recipient countries not on the selected ISO 3166-1 numeric block list. |
identity-allow-list-v2 | Identity | Recipient identities limited to the allowed on-chain identity list. |
identity-block-list-v2 | Identity | Recipient identities not on the selected on-chain identity block list. |
identity-verification-v2 | Identity | A claim expression, such as KYC or investor eligibility claims. |
investor-count-v2 | Limits | A maximum number of investors for the module instance. |
time-lock-v2 | Transfer | A minimum holding period before transfers can leave the holder. |
transfer-approval-v2 | Transfer | Transfer approvals from configured approval authorities. |
Legacy templates with moduleSetVersion: 1 can still use the older control IDs when your code reads or maintains an existing policy set, and only on deployments that keep legacy templates enabled. Do not mix legacy IDs such as country-allow-list, investor-count, or transfer-approval into a current-generation template. On create, the API rejects the incompatible field during request validation. On update or publish, the API can return the module-set compatibility error with the incompatible type IDs.
curl --request POST \
"$DALP_API_URL/api/v2/settings/compliance-templates" \
--header "X-Api-Key: $DALP_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"name": "Global capital raise policy",
"description": "Reusable capital raise controls for regulated assets",
"jurisdictions": [],
"moduleSetVersion": 2,
"modules": [],
"requiredControls": ["capital-raise-limit"]
}'The response includes the created template and a links.self path for the new resource.
Update template configuration
Update requests can change the name, description, jurisdictions, modules, and required controls. They cannot change the template's module set version. To use a different version, create a new template with the target moduleSetVersion and move the required modules or controls there.
DALP validates modules and required controls against the template's module set version on create, update, and publish. On create, an incompatible control triggers a request validation error on the field that supplied it. On update or publish, a current-generation template rejects controls that only belong to a legacy module set. If the API returns a module-set compatibility error, remove the incompatible controls or create a template with the matching version.
Publish a template
Publish the template when it is ready to appear in asset creation workflows:
curl --request PUT \
"$DALP_API_URL/api/v2/settings/compliance-templates/$TEMPLATE_ID/publish" \
--header "X-Api-Key: $DALP_API_TOKEN"Publishing changes isDraft to false. Published templates can be selected during asset creation. Draft templates stay editable until you publish them.
List and filter templates
Use the list endpoint to find templates by search, draft status, source, jurisdiction, or module generation. By default, the list includes DALP library templates and templates owned by the active organisation, with DALP library templates sorted first.
The list endpoint uses the standard collection query pattern:
| Query control | Use it for |
|---|---|
filter[q] | Search across template text fields. |
sort | Sort the collection. The default sort is name; use a leading minus sign for descending order, such as sort=-updatedAt. |
page[limit] and page[offset] | Page through large template libraries. |
filter[...] | Restrict the collection to templates that match a field value. |
Supported filter and sort fields:
| Field | Type | Use it for |
|---|---|---|
name | Text | Filter, search, or sort by template name. |
jurisdiction | Text | Return templates for a jurisdiction. GLOBAL returns templates with no specific jurisdiction. |
isDraft | Boolean | Return draft templates with true, or published templates and DALP library templates with false. |
moduleSetVersion | Number | Return templates for one compliance module generation. |
isSystem | Boolean | Return only DALP library templates with true, or only organisation templates with false. |
createdAt | Date | Filter or sort by creation time. |
updatedAt | Date | Filter or sort by last update time. |
For example, request recently updated current-generation draft templates when you are preparing a new policy set for your organisation:
curl --globoff \
"$DALP_API_URL/api/v2/settings/compliance-templates?filter[moduleSetVersion]=2&filter[isDraft]=true&filter[isSystem]=false&sort=-updatedAt&page[limit]=25" \
--header "X-Api-Key: $DALP_API_TOKEN"The response contains a data array of compliance templates. Each template includes id, name, description, jurisdictions, isSystem, isDraft, moduleSetVersion, organizationId, version, modules, requiredControls, createdBy, createdAt, and updatedAt. Response metadata lets clients render paginated tables. Facets for isSystem, isDraft, and moduleSetVersion let clients build source, status, and module-version filters without hard-coding the available values.
Read the template before you update it. Another operator or your other code may have changed the template version or draft status since your last read.
Error codes
When a write to a template fails a route-level check, the API returns a stable DALP-NNNN error code. A malformed request body, such as a control ID the schema does not recognise for the template's module set, is rejected earlier by request validation on the offending field path, not by one of the codes below. Once the request shape is valid, the platform resolves the template in your organisation's scope, confirms it is not an immutable DALP library template, and checks the modules and controls against the template's module set before it writes. These rejections arrive as a typed error. Read the code to decide whether the caller corrects the request and resends or escalates to operator follow-up. Each code below maps to a canonical entry in the platform API error reference.
| Code | HTTP | Category | When it happens |
|---|---|---|---|
| DALP-0680 | 403 | client | Legacy compliance templates are turned off on this deployment, so create rejects a template pinned to the older module set. Send moduleSetVersion: 2, or have an operator enable the legacy generation. |
| DALP-0095 | 404 | client | No template matches the requested ID in your organisation's scope. The ID may belong to another organisation, or the template may not be indexed yet. Update, publish, and delete return it. |
| DALP-0463 | 409 | client | The organisation already has a template with the submitted name. Create and update return it on a name collision. |
| DALP-0024 | 409 | client | The template is already published, so a repeat publish request conflicts with its current state. Publish returns it instead of creating a second version. |
| DALP-0168 | 409 | domain | The target is an immutable DALP library template, which cannot be modified. Update returns it. |
| DALP-0169 | 409 | domain | The target is an immutable DALP library template, which is already active and cannot be published. Publish returns it. |
| DALP-0167 | 409 | domain | The target is an immutable DALP library template, which cannot be deleted. Delete returns it. |
| DALP-0462 | 422 | domain | The modules or required controls belong to a different module generation than the template's module set. Update and publish return it. |
| DALP-0165 | 500 | operational | The create write returned no row after every guard passed, which points to a transient storage problem. The template was not saved. |
| DALP-0166 | 500 | operational | The update write returned no row after every guard passed, which points to a transient storage problem. The change was not saved. |
DALP-0095, DALP-0463, and DALP-0024 are correctable from the caller side: confirm the template ID and organisation scope, choose a unique name or update the existing template, or stop republishing a template that is already live. DALP-0680 means the deployment does not author templates on the older module set; send moduleSetVersion: 2 or have an operator enable the legacy generation. DALP-0168, DALP-0169, and DALP-0167 mean the target is a DALP library template that your organisation cannot change; copy its configuration into a new organisation template instead. DALP-0462 clears once you remove the controls from the other module generation or create a template with the matching module set. DALP-0165 and DALP-0166 report a write that did not persist after every guard passed, so the change was not saved; resend the request, and if the failure persists, escalate to operator follow-up with the request details rather than looping on the same call.
Related
Compliance modules API
List, register, install, configure, scope, and uninstall compliance modules through the API, on one token or globally across every bound token.
Token compliance expression API
Read and replace a token's on-chain compliance expression, the postfix rule that gates holder verification, through the DALP Platform API, SDK, and CLI.