POST /v1/admin/themes/packages
- operationId
uploadTheme- Auth
- Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
- Required permissions
The contract has no separate permission annotation; see the description below and the 403 response.
Description (from the contract)
Upload a custom cdnca.theme/v1 package (id custom.*). Packages with url(), @import, external links, script or undeclared classes are refused.
Request body
application/json · Required:Yes
Responses
uploadTheme Responses| Status | Description |
|---|
201 | Downloaded package Fields:package_sha256: string theme_id: string version: string name: object description?: object source: any requires_feature?: string downloaded_at: string(date-time) active: boolean tokens_url: string stylesheet_url: string preview_url?: string derived_from?: object |
|---|
413 | Larger than 8 MiB |
|---|
422 | Refused package |
|---|
↑ Back to list
GET /v1/admin/themes/packages/{sha}
- operationId
getThemePackage- Auth
- Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
- Required permissions
The contract has no separate permission annotation; see the description below and the 403 response.
Description (from the contract)
The cdnca.theme/v1 JSON of a package this installation stored (removed ones too) or a catalog theme, byte for byte (its SHA-256 is the path digest). The theme management page edits a copy of it and uploads the copy as a custom.* package whose derived_from names this package. Requires system_configuration.read.
Parameters
getThemePackage Parameters| Name | In | Type | Required | Description |
|---|
sha | path | string | Yes | — |
|---|
Responses
getThemePackage Responses| Status | Description |
|---|
200 | Package JSON |
|---|
404 | Never stored and not in the catalog |
|---|
What to do on failure
404 The resource does not exist or belongs to another tenant.
↑ Back to list
POST /v1/admin/themes/packages/{sha}/activate
- operationId
activateTheme- Auth
- Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
- Required permissions
The contract has no separate permission annotation; see the description below and the 403 response.
Description (from the contract)
Make a downloaded package the active theme of one console: no body is both consoles as before; {"slot":"admin"|"user"|"all"} names one. The admin console (admin, all) takes official themes only (built in, uploads and copies, or the io.cdnca market namespace); a third party's market theme is a user console theme. An admin activation records a new error page publication revision pinned to the theme; node default error pages follow the admin console, so a user activation republishes nothing.
Parameters
activateTheme Parameters| Name | In | Type | Required | Description |
|---|
sha | path | string | Yes | — |
|---|
If-Match | header | string | Yes | Activation revision the caller saw ("0" before any). |
|---|
Request body
application/json · Required:No
activateTheme Request body| Name | Type | Required | Description |
|---|
slot | string: all / admin / user | No | — |
|---|
Responses
activateTheme Responses| Status | Description |
|---|
200 | Activated Fields:revision: integer package_sha256: string theme_id: string error_page_publication_revision: integer error_page_republish_scopes: integer already_active?: boolean |
|---|
400 | Unknown slot |
|---|
403 | Permission denied |
|---|
404 | Not downloaded |
|---|
412 | Revision conflict |
|---|
What to do on failure
400 Fix the parameters or body per the field list; do not retry unchanged.403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.404 The resource does not exist or belongs to another tenant.412 The revision changed: read the latest ETag, decide again, then send the new If-Match.
↑ Back to list
PUT /v1/admin/themes/tenant-policy
- operationId
updateTenantThemePolicy- Auth
- Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
- Required permissions
The contract has no separate permission annotation; see the description below and the 403 response.
Description (from the contract)
Whether tenants in inherit mode may choose their theme. Audited as theme.tenant_policy.update.
Parameters
updateTenantThemePolicy Parameters| Name | In | Type | Required | Description |
|---|
If-Match | header | string | Yes | — |
|---|
Request body
application/json · Required:Yes
updateTenantThemePolicy Request body| Name | Type | Required | Description |
|---|
tenant_selection_allowed | boolean | Yes | — |
|---|
Responses
updateTenantThemePolicy Responses| Status | Description |
|---|
200 | New policy Fields:tenant_selection_allowed: boolean revision: integer |
|---|
412 | theme_revision_conflict |
|---|
What to do on failure
412 The revision changed: read the latest ETag, decide again, then send the new If-Match.
↑ Back to list
PUT /v1/admin/themes/tenants/{tenant_scope_id}/domains/{hostname}
- operationId
bindTenantThemeDomain- Auth
- Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
- Required permissions
The contract has no separate permission annotation; see the description below and the 403 response.
Description (from the contract)
Bind a sign-in hostname to the tenant (its sign-in page shows the tenant theme). Audited as theme.tenant_domain.bind.
Parameters
bindTenantThemeDomain Parameters| Name | In | Type | Required | Description |
|---|
tenant_scope_id | path | string(uuid) | Yes | — |
|---|
hostname | path | string | Yes | — |
|---|
Responses
bindTenantThemeDomain Responses| Status | Description |
|---|
200 | Tenant theme Fields:schema: const cdnca.theme.tenant/v1 tenant_scope_id: string(uuid) selection_mode: any platform_allows: boolean selection_allowed: boolean selected_package_sha256?: string assigned_by?: any effective_package_sha256: string effective_theme_id: string follows_platform: boolean revision: integer domains: array<string> choices: array<object> |
|---|
409 | theme_domain_conflict (bound to another tenant) |
|---|
What to do on failure
409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
↑ Back to list