Uniform Compositions & Component/Composition Patterns API
The Compositions & Component/Composition Patterns API from Uniform — 2 operation(s) for compositions & component/composition patterns.
The Compositions & Component/Composition Patterns API from Uniform — 2 operation(s) for compositions & component/composition patterns.
openapi: 3.0.3
info:
title: Uniform Platform Aggregates Compositions & Component/Composition Patterns API
version: '2.0'
tags:
- name: Compositions & Component/Composition Patterns
paths:
/api/v1/canvas-history:
get:
tags:
- Compositions & Component/Composition Patterns
parameters:
- in: query
name: compositionId
description: Specify the composition ID to get history for
required: true
schema:
type: string
format: uuid
- in: query
name: editionId
description: 'The edition ID. When set, gets history for a child edition of the compositionId.
'
schema:
type: string
format: uuid
- in: query
name: projectId
description: The project the composition(s) are on
required: true
schema:
type: string
format: uuid
- in: query
name: cursor
description: If a request returns a cursor, pass it in this query parameter to get the next page of results
schema:
type: string
maxLength: 1024
- in: query
name: releaseId
description: The release ID to get history for. Note that release history is independent of base histories
schema:
type: string
format: uuid
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/HistoryApiResponse'
'400':
$ref: '#/components/responses/BadRequestError'
'401':
$ref: '#/components/responses/UnauthorizedError'
'403':
$ref: '#/components/responses/ForbiddenError'
'404':
description: Composition not found
content:
text/plain:
schema:
type: string
'429':
$ref: '#/components/responses/RateLimitError'
'500':
$ref: '#/components/responses/InternalServerError'
/api/v1/canvas:
options:
tags:
- Compositions & Component/Composition Patterns
description: Handles preflight requests. This endpoint allows CORS
responses:
'204':
description: OK
get:
tags:
- Compositions & Component/Composition Patterns
description: "In addition to the named parameters below, this endpoint accepts the\nfollowing query parameter conventions which are pattern-validated and\ntherefore not declared as named parameters:\n\n* `filters.<field>[<op>]` — content filtering (documented below).\n* `select.<bucket>[<op>]` — data projection (documented below).\n\n#### Content filtering (`filters.*`)\n\nFiltering narrows list results to compositions matching field values.\nThe allowed field names are project-specific — they come from the\nproject's component definitions — which is why `filters.*` parameters\nare pattern-validated rather than declared as named parameters.\n\nSyntax: `filters.<field>[<operator>]=<value>`. `<field>` is one of:\n\n* A system field: `name`, `slug`, `type`, `created`, `modified`,\n `entityId`, `editionId`, `releaseId`, `patternId`, `creator`,\n `creatorSubject`, `author`, `authorSubject`, `projectMapId`,\n `projectMapNodeId`, `workflowId`, `workflowStageId`, `categoryId`,\n `labels`, `labelGroups`, `uiStatus`, or `locale`.\n* A component parameter, addressed as `parameters.<parameterId>`.\n Filtering by parameters requires also filtering to a single\n composition type (e.g. `filters.type[eq]=...`).\n* A sub-property of a parameter for certain parameter types:\n content references (`parameters.<id>.slug|name|type`), links\n (`parameters.<id>.type|projectMapNodeId`), and assets\n (`parameters.<id>.url|title|description|mediaType`).\n\n| Operator | Effect |\n|---|---|\n| `[eq]` / `[neq]` | Exact equality / inequality. |\n| `[match]` | Contains (text search) match; text-like fields only. |\n| `[starts]` | Prefix match. Value limited to letters, numbers, `_`, `.`, `-`, and spaces. |\n| `[lt]` / `[lte]` / `[gt]` / `[gte]` | Comparisons for number, date, and datetime fields (including `created` / `modified`). |\n| `[in]` / `[nin]` | Comma-separated list; matches any (OR) / none of the values. |\n| `[all]` | Comma-separated list; list-valued fields (e.g. `labels`, multi-selects) must contain every value (AND). |\n| `[def]` | `true` or `false`; whether the field has a value at all. |\n\nBehavior:\n\n* Values are single strings, or comma-separated lists for `[in]`,\n `[nin]`, and `[all]`. Dates accept `YYYY-MM-DD` or a full datetime\n string. An empty value is rejected — use `[def]` to test presence.\n* Not every operator is valid for every field; the allowed set depends\n on the field's type. An unsupported combination returns HTTP 400\n with the supported operators listed.\n* Malformed keys, unknown operators, and unknown field names return\n HTTP 400.\n* Filters match root compositions only.\n\nExamples:\n\n* `filters.type[eq]=landingPage` — only compositions of type `landingPage`.\n* `filters.modified[gte]=2026-01-01` — modified this year.\n* `filters.type[eq]=landingPage&filters.parameters.audience[in]=b2b,b2c` — parameter filter scoped to one type.\n* `filters.labels[all]=approved,featured` — has both labels.\n\n#### Data projection (`select.*`)\n\nProjection returns a subset of the response by pruning fields (parameters),\nfield types, and slots before values are resolved. The allowed names are\nproject-specific — they come from the project's component definitions and\ncontent types — which is why `select.*` parameters are pattern-validated\nrather than declared as named parameters.\n\nSyntax: `select.<bucket>[<operator>]=<value>`. Values are comma-separated\nlists of names. `*` is the only wildcard and matches zero or more\ncharacters (e.g. `seo_*`).\n\n| Parameter | Effect |\n|---|---|\n| `select.fields[only]=a,b` | Keep only the named fields/parameters; drop everything else. |\n| `select.fields[except]=a,b` | Drop the named fields/parameters; keep everything else. |\n| `select.fields[locales]=a,b` | For the named fields that survive filtering, return the full per-locale value map instead of only the requested locale's value. |\n| `select.fields[blockDepth]=N` | Limit how many levels of block field children are kept. `0` removes all block fields; `preserveAll` prevents projection from trimming fields inside block children. |\n| `select.fieldTypes[only]=a,b` | Keep only fields of the named types (type IDs such as `text`, `richText`, `asset`). |\n| `select.fieldTypes[except]=a,b` | Drop fields of the named types. |\n| `select.slots[only]=a,b` | Keep only the named slots. |\n| `select.slots[except]=a,b` | Drop the named slots. |\n| `select.slots[depth]=N` | Limit how many levels of nested components are kept in slots. |\n| `select.slots.<name>[depth]=N` | Depth limit for one specific slot; overrides `slots[depth]`. |\n\nBehavior:\n\n* Projection applies recursively at every component and block in the\n returned tree, and is forwarded into entries resolved through reference\n fields.\n* When operators combine, all `[only]` sets are intersected first, then\n `[except]` sets are subtracted — exclusion always wins.\n* Unknown field, slot, or type names are silent no-ops (the tree shape is\n preserved; non-matching content is simply absent). Unknown operators\n return HTTP 400.\n* An empty list (`select.fields[only]=` or `select.slots[only]=`) strips\n every member of that bucket; `[except]=*` is equivalent.\n* `[depth]` counts nesting within a single fetched tree and resets inside\n referenced entries.\n\nExamples:\n\n* `select.fields[only]=title,slug` — keep only titles and slugs, everywhere in the tree.\n* `select.fieldTypes[except]=richText` — everything except rich-text fields.\n* `select.fields[only]=title&select.slots[only]=` — root title only, with all slots flattened.\n* `select.slots[depth]=2&select.fields[only]=label,url` — two levels of nested components, trimmed to `label` and `url`.\n"
parameters:
- $ref: '#/components/parameters/compositionId'
- $ref: '#/components/parameters/componentId'
- $ref: '#/components/parameters/versionId1'
- $ref: '#/components/parameters/compositionIDs'
- $ref: '#/components/parameters/createdBy2'
- $ref: '#/components/parameters/keyword2'
- $ref: '#/components/parameters/limit1'
- $ref: '#/components/parameters/offset1'
- $ref: '#/components/parameters/orderBy2'
- $ref: '#/components/parameters/facetBy'
- $ref: '#/components/parameters/pattern1'
- $ref: '#/components/parameters/patternType'
- $ref: '#/components/parameters/withPatternType'
- $ref: '#/components/parameters/projectId3'
- $ref: '#/components/parameters/projectMapId1'
- $ref: '#/components/parameters/projectMapNodeId'
- $ref: '#/components/parameters/projectMapNodePath'
- $ref: '#/components/parameters/skipEnhance'
- $ref: '#/components/parameters/skipPatternResolution'
- $ref: '#/components/parameters/skipParameterResolution'
- $ref: '#/components/parameters/skipOverridesResolution1'
- $ref: '#/components/parameters/slug1'
- $ref: '#/components/parameters/categories'
- $ref: '#/components/parameters/state1'
- $ref: '#/components/parameters/type2'
- $ref: '#/components/parameters/uiStatus1'
- $ref: '#/components/parameters/attachedToProjectMap'
- $ref: '#/components/parameters/updatedBy2'
- $ref: '#/components/parameters/withComponentIDs2'
- $ref: '#/components/parameters/withTotalCount'
- $ref: '#/components/parameters/withUIStatus2'
- $ref: '#/components/parameters/withWorkflowDefinition1'
- $ref: '#/components/parameters/withProjectMapNodes'
- $ref: '#/components/parameters/withContentSourceMap'
- $ref: '#/components/parameters/locale2'
- $ref: '#/components/parameters/releaseId'
- $ref: '#/components/parameters/search1'
- $ref: '#/components/parameters/searchSemantic'
- $ref: '#/components/parameters/editions1'
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'200':
description: OK
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/CompositionListResponse'
- $ref: '#/components/schemas/CompositionApiResponse'
'400':
$ref: '#/components/responses/BadRequestError'
'401':
$ref: '#/components/responses/UnauthorizedError'
'403':
$ref: '#/components/responses/ForbiddenError'
'404':
description: Composition not found
content:
text/plain:
schema:
type: string
'429':
$ref: '#/components/responses/RateLimitError'
'500':
$ref: '#/components/responses/InternalServerError'
put:
tags:
- Compositions & Component/Composition Patterns
description: Upserts a composition
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- projectId
- state
- composition
properties:
projectId:
type: string
format: uuid
description: The project ID to upsert the composition to
state:
type: number
minimum: 0
maximum: 64
description: The publishing state to upsert into. 0 = draft, 64 = published
composition:
$ref: '#/components/schemas/RootComponentInstance'
pattern:
description: Indicates if the composition is a pattern that can be referenced in other compositions
type: boolean
default: false
created:
description: This field is ignored if present
type: string
modified:
description: This field is ignored if present
type: string
categoryId:
type: string
format: uuid
description: Reference to the category this component definition belongs to
nullable: true
default: null
description:
type: string
description: A description of the component definition
maxLength: 2024
nullable: true
default: null
previewImageUrl:
type: string
description: A preview image URL of the component definition
maxLength: 2024
nullable: true
default: null
releaseId:
type: string
format: uuid
description: The release this composition belongs to. If not set, it belongs to the base
workflowId:
type: string
format: uuid
description: The workflow ID assigned to this composition, if any
workflowStageId:
type: string
format: uuid
description: The stage ID the composition is in within its assigned workflow. If undefined, it is implicitly in the initial stage of the workflow
editionId:
type: string
format: uuid
description: 'The edition ID. When set, this is a child edition of the composition in _id.
'
editionName:
type: string
maxLength: 100
description: 'The name of the composition or edition as shown in the editions listing.
Describes the purpose of an edition.
'
editionPriority:
type: integer
description: 'The priority of the edition or composition. Higher numbers are higher priority.
When multiple editions enable the same locale, the highest priority edition is used.
'
additionalProperties: false
parameters:
- in: header
name: X-If-Unmodified-Since
description: 'Optional concurrency control header. If provided, the server will check that the composition
has not been modified since this timestamp. If the timestamp doesn''t match the current
modified timestamp, a 409 Conflict response will be returned.
'
required: false
schema:
type: string
example: '2024-01-15T10:30:45.123Z'
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'204':
description: OK
'400':
$ref: '#/components/responses/BadRequestError'
'401':
$ref: '#/components/responses/UnauthorizedError'
'403':
$ref: '#/components/responses/ForbiddenError'
'409':
description: Conflict - Composition has been changed since being loaded
content:
text/plain:
schema:
type: string
'429':
$ref: '#/components/responses/RateLimitError'
'500':
$ref: '#/components/responses/InternalServerError'
delete:
tags:
- Compositions & Component/Composition Patterns
description: Deletes or unpublishes a composition
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- compositionId
- projectId
properties:
compositionId:
type: string
format: uuid
description: 'The ID of the composition to delete.
When editionId is also passed, the composition remains and an edition under it is deleted.
When editionId is omitted, and the composition has editions, all editions will also be deleted along with the composition.
'
editionId:
type: string
format: uuid
description: 'The edition ID to delete. When set, this deletes a child edition of the compositionId.
The composition will remain when an edition is deleted.
If the composition ID is specified as the edition ID, the composition will be deleted _but any other editions will remain_ (this is used for unpublishing).
'
projectId:
type: string
format: uuid
description: The ID of the project the composition to delete belongs to
releaseId:
type: string
format: uuid
description: 'The release the composition to delete belongs to. If not set, it belongs to the base.
Note: Deleting a composition from a release will not delete the composition from the base
'
state:
type: number
minimum: 0
maximum: 64
description: The state to delete (0 = draft, 64 = published [causes unpublishing], unspecified = all)
additionalProperties: false
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
'204':
description: OK
'400':
$ref: '#/components/responses/BadRequestError'
'401':
$ref: '#/components/responses/UnauthorizedError'
'403':
$ref: '#/components/responses/ForbiddenError'
'429':
$ref: '#/components/responses/RateLimitError'
'500':
$ref: '#/components/responses/InternalServerError'
components:
parameters:
limit1:
in: query
name: limit
description: 'Maximum number of records to return
This is a list query parameter and cannot be used with any primary query parameters
'
schema:
type: integer
minimum: 1
maximum: 1000
default: 100
type2:
in: query
name: type
description: 'The component type (by public ID) to filter by. Note that this filters the root composition type only; components in slots are not matched by this filter.
This is a list query parameter and cannot be used with any primary query parameters
'
style: form
schema:
type: array
items:
type: string
attachedToProjectMap:
in: query
name: attachedToProjectMap
style: form
description: 'Filters out compositions without attached node or filters out compositions with attached nodes
if set to false. If not specified, no filtration is applied.
This is a list query parameter and cannot be used with any primary query parameters
'
schema:
type: boolean
versionId1:
in: query
name: versionId
description: 'Specify a historical composition version ID to fetch (retrieved from the canvas-history API).
Must be used with the `compositionId` parameter
'
schema:
type: string
maxLength: 1024
projectMapNodePath:
in: query
name: projectMapNodePath
description: 'Specify a single composition to fetch by associated project map node path. The response will be a single composition.
This is a primary query parameter and cannot be used with any other primary query parameters
'
schema:
type: string
offset1:
in: query
name: offset
description: 'Number of records to skip
This is a list query parameter and cannot be used with any primary query parameters
'
schema:
type: integer
minimum: 0
state1:
in: query
name: state
description: 'Publishing state to fetch. 0 = draft, 64 = published.
This is a list query parameter and cannot be used with any primary query parameters
'
schema:
default: 64
type: number
minimum: 0
maximum: 64
skipOverridesResolution1:
in: query
name: skipOverridesResolution
description: 'If true, any pattern override data is not resolved by the API.
This is intended for internal use in the Canvas editor and should not be used.
Passing this parameter automatically implies `withComponentIDs` is true
'
schema:
type: boolean
default: false
createdBy2:
in: query
name: createdBy
description: 'Filters composition lists by the user who created them. The user is specified by their identity subject.
This is a list query parameter and cannot be used with any primary query parameters
'
schema:
type: string
patternType:
in: query
name: patternType
description: 'This specifies which type of patterns to return. This query parameter has no effect when `pattern` is false.
* `all` - Returns all pattern instances
* `component` - Returns only component patterns
* `composition` - Returns only composition patterns
'
schema:
type: string
enum:
- all
- component
- composition
default: all
search1:
description: 'Search on textual fields of a composition.
Matches against fully rendered content including resolved pattern content.
Use this for "where does this content appear" queries.
Note: For long text fields, the tail of the text is not guaranteed to be searchable.
Example: ?search=hello
'
in: query
name: search
schema:
type: string
withUIStatus2:
in: query
name: withUIStatus
deprecated: true
description: 'Returns the UI status string of the composition.
This internal status is subject to change without notice and is thus marked deprecated to discourage use of internal data
'
schema:
type: boolean
default: false
projectId3:
in: query
name: projectId
description: The project the composition(s) belong to
required: true
schema:
type: string
format: uuid
withPatternType:
in: query
deprecated: true
name: withPatternType
description: Includes the `patternType` attribute in the response
schema:
type: boolean
default: false
searchSemantic:
deprecated: true
description: 'BETA: Semantic search using vector similarity to find content by meaning.
Matches against source content only - pattern base content matches the pattern itself, not consumers.
Use this for "where is this content defined" queries.
Requires AI credits.
'
in: query
name: searchSemantic
schema:
type: string
skipEnhance:
in: query
name: skipEnhance
deprecated: true
description: 'Signals an enhancer proxy to skip processing enhancements to the data and return raw data only.
This improves performance if you do not require enhanced component data.
If calling the Canvas API directly with no enhancer proxy, this has no effect
'
schema:
type: boolean
default: false
keyword2:
in: query
name: keyword
description: 'Matches compositions where their name, slug, or definition name contains the specified keyword.
NOT a full-text search; does not match composition contents.
This is a list query parameter and cannot be used with any primary query parameters
'
schema:
type: string
maxLength: 256
categories:
in: query
name: categories
description: Filtration by category ID. An empty string can be used to include records without a category.
schema:
type: array
items:
type: string
projectMapId1:
in: query
name: projectMapId
description: 'Specify a project map ID to fetch by path or node ID from.
If not specified, the default project map for the projectId is used.
Only used when fetching by projectMapNodeId or projectMapNodePath
'
schema:
type: string
format: uuid
withContentSourceMap:
in: query
name: withContentSourceMap
deprecated: true
description: Includes content source map metadata on supported parameters
schema:
type: boolean
default: false
withWorkflowDefinition1:
in: query
name: withWorkflowDefinition
description: 'Returns the definition of any attached workflow along with the composition data
'
schema:
type: boolean
default: false
skipParameterResolution:
in: query
name: skipParameterResolution
deprecated: true
description: 'This parameter is unused and has no effect. Passing this parameter will become an error in the future
'
schema:
type: boolean
default: false
releaseId:
in: query
name: releaseId
description: 'The ID of a release to fetch the content for.
- When unspecified, all release content is excluded from the result(s).
- When specified, all content is returned as it would appear in the release if it was released now. This includes both content copied to the release and changed, as well as content that is not part of the release.
Content copied to a release can be differentiated from base content by the `releaseId` property on the content. If the content is not copied to the release, this property will be null
'
schema:
type: string
format: uuid
updatedBy2:
in: query
name: updatedBy
description: 'Filters composition lists by the user who last updated them. The user is specified by their identity subject.
This is a list query parameter and cannot be used with any primary query parameters
'
schema:
type: string
projectMapNodeId:
in: query
name: projectMapNodeId
description: 'Specify a single composition to fetch by associated project map node ID. The response will be a single composition.
This is a primary query parameter and cannot be used with any other primary query parameters
'
schema:
type: string
format: uuid
compositionIDs:
in: query
name: compositionIDs
description: 'Specify multiple composition IDs to fetch. The response type will be a list.
This is a primary query parameter and cannot be used with any other primary query parameters.
When `editions=raw`, this parameter matches on composition or edition IDs and edition resolution is disabled.
'
style: form
schema:
type: array
items:
type: string
format: uuid
editions1:
in: query
name: editions
description: "Controls the edition resolution behavior.\n\nauto: (default) Editions are evaluated automatically and the best matching edition is returned.\n When a locale is provided, the edition with the highest priority that enables that locale matches\n Without a locale, the default edition is matched\n\nall: Every edition is returned as a separate row.\n Note: this has no effect when used with compositionId which always returns a single result.\n\nraw: the compositionId and compositionIDs parameters target exact edition/composition IDs and no edition resolution is performed.\n compositionId or compositionIDs MUST be provided with this option.\n If versionId is passed, this is always enabled.\n"
schema:
type: string
enum:
- auto
- all
- raw
default: auto
compositionId:
in: query
name: compositionId
description: 'Specify a single composition ID to fetch. The response will be a single composition.
This is a primary query parameter and cannot be used with any other primary query parameters.
When `editions=raw`, this parameter matches on composition or edition IDs and edition resolution is disabled.
'
schema:
type: string
format: uuid
locale2:
in: query
name: locale
description: 'One or more locales to filter and localize by.
For list responses, only compositions that enable one of the specified locales _or enable no locales_ will be returned. When more than one locale is passed, the list matches with an OR on each locale.
For all types of response, the response will be localized to include only the first matching locale''s data.
This parameter accepts a single value, a comma-delimited list of values, or the Accept-Language header syntax. Examples:
en-US
fr-CA,fr
de-AT;q=0.9,de-DE;q=0.8,en;q=0.7
When this parameter is not passed, all locales'' data will be returned.
If a composition is requested by ID and does not possess any of the specified locales, HTTP 404 will be returned
'
schema:
type: string
maxLength: 128
withProjectMapNodes:
in: query
name: withProjectMapNodes
description: Includes project map node information in the composition results
schema:
type: boolean
default: false
withTotalCount:
in: query
name: withTotalCount
description: 'Controls whether the total count of results will be returned along with the current results page in a list.
Has no effect when not fetching a list. This does impact performance when enabled
'
schema:
type: boolean
facetBy:
in: query
name: facetBy
deprecated: true
description: Returns counts for distinct values of the specified field or fields (provided as comma-separated IDs).
style: form
schema:
type: string
pattern1:
in: query
name: pattern
description: 'Matches compositions based on whether they are a pattern composition or a regular composition.
If true, only pattern compositions will be returned.
If false, only regular compositions will be returned.
If omitted or ''any'', both pattern and regular compositions will be returned.
This is a list query parameter and cannot be used with any primary query parameters
'
schema:
oneOf:
- type: boolean
- type: string
enum:
- any
componentId:
in: query
name: componentId
description: 'Specify a single component ID to fetch the component''s composition defaults. The response will be a single composition.
This is a primary query parameter and cannot be used with any other primary query parameters
'
schema:
type: string
minLength: 1
maxLength: 100
pattern: ^[a-zA-Z0-9-_]+$
withComponentIDs2:
in: query
name: withComponentIDs
description: 'If true, the `_id` unique identifier of each non-root component will be part of the response data.
If false, the `_id` will not be present in the API response
'
schema:
type: boolean
default: false
slug1:
in: query
name: slug
description: 'Specify a single composition to fetch by slug. The response will be a single composition.
This is a primary query parameter and cannot be used with any other primary query parameters
'
schema:
type: string
orderBy2:
in: query
name: orderBy
description: 'Sets the sorting of the results. If unspecified, results are sorted by name ascending.
Allowed values are: updated_at_DESC, updated_at_ASC, created_at_DESC, created_at_ASC,
name_DESC, name_ASC, slug_DESC, slug_ASC.
When using primary query parameters, this pa
# --- truncated at 32 KB (72 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/uniform/refs/heads/main/openapi/uniform-compositions-component-composition-patterns-api-openapi.yml