In brief
From this page’s summary fields, verified 2026-11-10. Sources in each section.- Authentication (details in section Authentication)
- OAuth 2.0 (password, PKCE), API key
- Rate limit (details in section Limits & quirks)
- CMP V2: 5,000 requests/min and 500,000/month per account
- Webhooks (details in section Events & webhooks)
- Asset events set up by App Support (API key, batched, 5 retries); v4 render callbacks
- Pagination (details in section At a glance)
- offset (listing-offset + listing-limit 20/50/100); v4 media lists 50 per page
- API spec (details in section Stored API specs)
- OpenAPI 3.1: CMP V2 (36 ops) + Storyteq API v4 (5 ops, 5 webhooks)
Storyteq publishes several separate integration surfaces rather than one general-purpose API:
- CMP V2 API ("Content Management Platform API V2"): a lightweight REST API over the LUMA back end for assets, taxonomy, lenses, projects and workflows. Its OpenAPI file is public S17 S19.
- Storyteq API (Creative Automation) v4: render media from Adaptation Studio templates. Public OpenAPI file with webhook definitions S18.
- Embeddable components: the Asset Picker (web component or iframe) and the Dynamic Asset Transformation (DAT) web component, plus URL-based image transforms on the CDN S8 S12 S13.
- Identity Broker: OIDC + PKCE sign-in for external integrations such as Figma and Jira S4.
- Asset event webhook service: outbound asset change events S6.
The OpenAPI files sit on a Swagger UI portal at developer.storyteq.com. Prose documentation sits on docs.storyteq.com, which has no REST reference S17 S2. All API access needs credentials issued by the Storyteq account team S19 S18.
At a glance
https://enterprise.api.storyteq.com/cmp/v2/ (spec server); the auth example uses https://enterprise.api-dev.storyteq.com/cmp/v2/token, and the Asset Picker routes to https://enterprise.api-${env}.storyteq.com S19 S9. The tenant is passed in a CMP-Tenant header (the customer's CMP instance URL, https://{tenant}.storyteq.com) S19. v4: https://api.{region}.storyteq.com/v4 with region = europe-west1 (default) or us-east4; https://api.storyteq.com/v4 is marked "Legacy, Deprecated" S18. Internal LUMA (Asset Picker default): {host}/api/{domain}/com.intrepia.luma.{endpoint} S9. CDN transforms: https://cdn.assets.storyteq.com/{tenant}/version/{asset-id}/transform/image/… S13 (the path segment after the host is shown as ca in the example; its meaning is not documented)./token with client_id (cmp-v2-<dev|uat|prd>), username, password and the CMP-Tenant header; bearer JWT on later calls S19. v4: static bearer token obtained from "your regular contact person" S18. External integrations: OIDC authorization code + PKCE through the Identity Broker (Keycloak) S4 S5. Asset Picker (internal): API key + lens ID in attributes S9. Webhooks to your endpoint: X-API-Key header S7.notifications with type: webhook and a route URL; events MediaQueued, MediaRendering, MediaUploading, MediaFinished, MediaFailed S18.app.storyteq.io, app.storyteq.work, app.storyteq.com for the Asset Picker; `cmp-v2-<devAuthentication
CMP V2 (password grant) S19
- Ask the account team for a client ID, a username/password and your CMP-Tenant value (your CMP instance URL).
- POST
{base}/tokenwith headersContent-Type: application/jsonandCMP-Tenant: {tenant}and a JSON body:client_id,username,password,grant_type: "password". - Use the returned
access_token(JWT) asAuthorization: Bearer …with theCMP-Tenantheader on every call. - Refresh with
grant_type: "refresh_token"and therefresh_token.
- Without credentials, the API answers
400 {"error": "Authorization field missing"}S36. - The spec documents only this flow for CMP V2; no client-credentials or authorization-code flow is described for it.
Storyteq API v4 (bearer token) S18
- Every request carries
Authorization: Bearer {token}. Tokens are issued by Storyteq; no self-service creation is documented. An unauthenticated call to/v4/content/templates/returns401 {"message":"Unauthenticated."}S36.
Identity Broker (external integrations) S4 S5 S11
- The user enters their tenant URL in the integration and clicks Connect.
- The Identity Broker finds the tenant's identity provider and region and builds the redirect. Sign-in opens in a new browser tab or window (SSO or Storyteq credentials).
- The IdP returns an authorization code; the integration exchanges it (with the PKCE verifier) for access and refresh tokens.
- The integration polls the broker to detect completion (no WebSocket). The session times out after 5 minutes.
- Broker endpoints are limited to 20 requests per minute. Endpoint paths and client registration: Not public.
- Storyteq CMP uses Keycloak; tenants still on LUMA sign-in are being migrated S4.
Asset Picker credentials (internal integrations) S8 S9
- The host passes
domain,domainId,apiKeyandlensId(one lens = one curated set of assets). Users do not sign in. External integrations instead setapiIntegration(external-prod,external-uat…) and sign users in through the Identity Broker.
Core resources
CMP V2 operations, derived from the OpenAPI file (36 operations; all except /token require the bearer token and CMP-Tenant) S19.
| Resource | Endpoints | Notes |
|---|---|---|
| Authentication | POST/token | Password and refresh-token grants |
| Discovery: domains | GET/ListUserDomains | Domains the user can access; IDs needed elsewhere. IDs can change if configuration changes |
| Discovery: configuration | GET/ListFolders, /ListSites, /ListLensesForDomain, /ListTransforms, /ListTypeTree, /ListTypeFieldsByType, /ListTypeSchema, /ListGenera, /GetGenus, /ListKeywords | Folders, portal sites, lenses, transforms (derivative recipes), type tree, type fields, project schemas, taxonomy genera and keywords |
| Assets: search & list | GET/ListAssets | domainID, filters (URL-encoded JSON), lensID, available, inherit, sort by name / created / modified / type / state |
| Assets: read | GET/GetAsset, /GetAssetInfo, /GetAssetFields, /GetAssetTaxonomy, /ListAssetNarratives, /ListAssetAvailability, /GetAssetURLs | Metadata, extended info, fields, keywords, narratives, availability windows, external (public) URLs |
| Assets: write | POST/SetAssetFields, /SetAssetNarrative, /EditAssetKeywords | Field values, narratives, keyword binding |
| Renditions / downloads | GET/GetAssetDerivativeMenu, /DownloadAssetDerivative, /DownloadAssetPreview | Signed temporary link to a derivative (operation=Link); previews generated on demand |
| Projects | POST/CreateProjectRoot, GET/GetProject, /GetProjectRootTypesForDomain, /ListUserProjectNodes, POST/AddProjectResourcesFetch | Create and read workflow projects; add a resource from a URL |
| Workflows | GET/ListProcesses, /ListAssetWorkflows, /GetWorkflowUserTransitions, POST/WorkflowStart, /WorkflowTransition | Start a process on a project and move it through transitions |
| Users / groups | none | Not exposed in CMP V2 |
| Uploads | none (only AddProjectResourcesFetch from a URL) | Bulk upload and download are out of scope; contact the integrations team S19 |
| Rights | GET/ListAssetAvailability | Availability windows; phases (Quarantined / Active / Expired) |
Storyteq API v4 (creative automation) S18
| Resource | Endpoints | Notes |
|---|---|---|
| Templates | GET/content/templates/, GET/content/templates/{templateId} | Templates the token can use, with parameter configuration; version status Draft (Ad Builder) / Production / Draft (After Effects) |
| Media (renders) | POST/content/templates/{templateId}/media, GET/content/templates/{templateId}/media, GET/content/media/{mediaId} | Create media from template_parameters key-value pairs; status queued → rendering → uploading → finished / failed; download_urls when done. 409 and 422 errors defined |
Canopy API V1 (deprecated; read only, not archived because of its licence) S20: 11 GET operations on /domains, /domains/{id}/lenses, /resources, /resources/{id} (info, derivatives, previews, external URLs, latest atom) and /env; offset paging with limit (max 200) and offset.
Data model
- Domain: hierarchical container for configuration and objects (organisation → business unit → market). Access flows down, never up or sideways S19.
- Type: the backbone for assets and projects (fields, taxonomy, milestones, states, roles, workflow) S19.
- Asset (called resource internally): integer
assetIDplus a UUID (assetUuid) that persists across versions. Each binary version is an atom (atomId) S7 S20. Event supertypes: Resource, Project, Adaptation, Template S7. - Metadata: custom fields per type, narratives (named free-text fields), taxonomy keywords grouped in genera, tags S19.
- Lifecycle:
phase(Quarantined, Active, Expired) and an independent availability window S19 S26. - Derivatives: produced by transforms (engines Passthru, Chaos, Entropy) per asset type. The original file cannot be downloaded through the API, only a derivative S19 S22.
- Lens: saved filter (type, file type, phase, keywords with all / any / none) mirroring a portal view S19.
- Site: a front-end portal; several per domain S19.
Search & querying
- Simple search by asset name; simple filters (asset ID list, phase, available).
- Complex filters: a URL-encoded JSON array. The
searchFiltertype takesclauses, each withflags(Fuzzy,Name,Keyword,Field,Metadata,Tag), an optional fieldnameand avalue. Flags inside one clause are OR'ed; clauses and filters are AND'ed. - Other filter types use LUMA class names, e.g.
com.intrepia.luma.KeywordFilter(keyword IDs),TypeFilter(with descendants) andPeriodFilter(created / modified date ranges). - Responses include real-time counts per filter (faceted search).
- Lens-based search: pass
lensIDto reproduce a portal view. - Max page size 100. A maximum result window is not documented. Storyteq states that the API does not support bulk extraction, wide filters with nested iteration, or polling "in any shape or form". Use webhooks for change detection.
Uploads & binaries
- No binary upload in the public APIs. CMP V2 can only attach a project resource fetched from a URL (
AddProjectResourcesFetch) S19. Bulk upload or download needs the integrations team S19. - Download flow:
ListAssets→GetAssetDerivativeMenu(choose a transform) →DownloadAssetDerivativewithoperation=Link, which returns a temporary signed URL. Derivatives need a transform set up in advance; ask the account team to create transforms S19. - Previews:
DownloadAssetPreviewbuilds previews on request and asynchronously. A404can mean "not ready yet", so retry with increasing delays S19. - Public URLs:
GetAssetURLsreturns external URLs. Asset Picker links using public URLs do not expire; service-account links have their own validity period S19 S8. - On-the-fly images: CDN URLs with path segments
{id}:{parameters}(e.g.resize:fit-in:800x600/quality:85/format:webp). Signing or auth for these URLs: Not public S13. - Rendered media (v4): the
download_urlsobject on a finished media item S18.
Events & webhooks
Asset event webhook service S6 S7
| Aspect | Detail |
|---|---|
| Events | CREATED, EDITED (merged per asset per interval), DELETED (moved to Trash, restorable), PURGED (permanent; bypasses filters), REVERSION (new binary/version) |
| Configuration | Through Storyteq App Support, not self-service. YAML keys under assetUpdater.webhooks: url, enabled, apikey, headers, resourceTypes, eventTypes, filters |
| Filters | resourceTypes (default Resource), eventTypes, parentId (only top-level assets by default), and filter groups on keywords, additionalFields, state, schemaId, typeId, domainId, parentId with AND / ANY / NONE |
| Payload | POST JSON {count, webhookTimestamp, events[]}; each event: eventId (UUID, use for dedup), eventTimestamp, eventType, assetId, assetUuid, atomId |
| Batching | About every minute; 100 events per request by default (smaller on request); 16 MB cap |
| Auth to your endpoint | X-API-Key header (secret held in GCP Secret Manager by Storyteq) plus optional custom headers. No payload signature. No OAuth |
| Retries | Non-2xx: up to 5 retries, exponential back-off 1 → 8 minutes. 4xx not retried. After 24 h, events go to an internal dead-letter store |
| Replay / monitoring | No self-service replay (ask App Support with event IDs); no delivery dashboard |
Unverified The two pages disagree on undeliverable events: the explanation page says they are "dropped" after 24 hours, the reference says they go to a dead-letter store. The reference lists event types in upper case, while its YAML examples use title case ("Edited") S6 S7.
v4 render notifications S18: add notifications: [{type: "webhook", route: "https://…"}] to a media request. Defined callbacks: MediaQueued, MediaRendering, MediaUploading, MediaFinished, MediaFailed. Signature and retry policy: Not public.
Limits & quirks
- CMP V2 is for UI-scale use: small subsets of data for pickers, metadata reads and edits, project creation. No bulk, no polling, no original-file download S19.
- Rate limits are "general guidelines" (5,000/min, 500,000/month per account) S19. A fair-use policy in the spec forbids reselling data and circumventing limits S19.
- IDs may change when the DAM configuration changes. Cache them but plan to rediscover S19.
- Assets visible in the front end must be Active, available and usually carry keywords matching the lens S19.
- Preview 404s on first request are normal (asynchronous generation) S19.
- Two v4 docs: the API root still points to an Apiary reference (
storyteq.docs.apiary.io) while the Developer Portal serves the OpenAPI 3.1 file S36 S38 S17. - Asset Picker
apiIntegration: the parameters page also mentions anexternal-sitevalue that is not in the accepted-values list S9 Unverified. - Generative Expand is unavailable for images of 4,000 px or more in either dimension S14 S28.
- Agent Console is not an API product: there are no public endpoints for agents S15 S16.
SDKs, tools & code samples
| Tool | Language | Status | Source |
|---|---|---|---|
storyteq-api-php (Composer storyteq/storyteq-api-php) | PHP, API v4 | Self-described as incomplete; archived 2024-04-18 | S34 |
Asset Picker web component (asset-picker.umd.js, <asset-picker>) / iframe | JavaScript | Current; loaded from app.storyteq.com/asset-picker/ | S10 S9 |
DAT web component (<cmp-dat>) | JavaScript | Current; standalone mode for testing | S12 |
storyteq-video-player, platform-integration repos | JavaScript / TypeScript | Public repos without documentation; not presented as SDKs | S35 |
No npm, PyPI or NuGet package was found. No llms.txt on storyteq.com or docs.storyteq.com S36.
Changelog of the API
| Date | Change | Source |
|---|---|---|
| 2026-06-25 | Last-Modified date of the CMP V2 and v4 OpenAPI files on the Developer Portal | S36 S17 |
| Undated | Non-regional v4 host api.storyteq.com/v4 marked "Legacy, Deprecated"; regional hosts europe-west1 and us-east4 introduced | S18 |
| Undated | Canopy API V1 (CanopyCloud era) deprecated for new development and removed from the portal list | S20 S17 |
| Undated | LUMA sign-in clients migrating to Keycloak; Identity Broker for external integrations | S4 |
| 2024-04-18 | PHP client for v4 archived | S34 |
The product changelog has no API entries S21. Storyteq does not publish a dated API changelog.