application · active
Topolo Design
Standalone brand-governed design workspace for static media and short animated creative exports.
Documentation map
- Topolo Design — Standalone brand-governed design workspace for static assets and short animated creative clips.
Authority and runtime
- System ID
topolo-design- App IDs
- app_topolo_design
- Owners
- marketing-platform
- Repositories
- apps/TopoloDesign
- Hosts
- https://design.topolo.app, https://design.stg.topolo.us, https://design.topolo.dev
- Dependencies
- topolo-auth, topolo-brand, topolo-notify, applications-packages
Security and data ownership
- Risk tier
- standard
- Tenant isolation
- organization_scoped
- Privacy classification
- confidential
- Storage
- d1, r2
- Export and deletion
- implemented
- Enterprise ready
- no
Source-derived capability inventory
Source revisions: apps/TopoloDesign@b07fc4d973a6c3b8285bd2f506e830f88544e0b8
Declared actions: 38 · API routes: 6 · UI routes: 12
{
"id": "topolo-design",
"name": "Topolo Design",
"slug": "topolo-design",
"kind": "application",
"visibility": "public",
"repo_paths": [
"apps/TopoloDesign"
],
"source_revisions": [
{
"source_path": "apps/TopoloDesign",
"repository": "apps/TopoloDesign",
"revision": "b07fc4d973a6c3b8285bd2f506e830f88544e0b8",
"ref": "origin/staging"
}
],
"source_counts": {
"source_files": 78,
"test_files": 57,
"test_cases": 0,
"migration_files": 12,
"database_tables": 0,
"manifests": 1,
"deploy_targets": 2,
"actions": 38,
"mobile_contracts": 0,
"notifications": 1,
"package_manifests": 1,
"deployment_configs": 0
},
"manifests": [
{
"source_path": "apps/TopoloDesign/topolo.app.json",
"service_slug": "topolo-design",
"name": "topolo-design",
"app_id": "app_topolo_design",
"compatibility_date": "2026-05-05",
"primary_target": null,
"environments": [
"development",
"production",
"staging"
],
"targets": [
{
"name": "api",
"kind": "worker",
"directory": "apps/api",
"main": "src/worker.ts",
"worker_name": "topolo-design-api",
"subdomain": null,
"healthcheck_path": "/api/health",
"variable_names": [
"AUTH_BASE_URL",
"DESIGN_APP_URL",
"LIBRARY_OWNER_ORGANIZATION_ID",
"LIBRARY_OWNER_WORKSPACE_ID",
"NEXUS_GATEWAY_URL",
"RENDER_SERVICE_URL",
"TOPOLO_NOTIFY_URL"
],
"secret_names": [],
"bindings": [
{
"kind": "d1",
"binding": "DESIGN_CORE_DB",
"target": null
},
{
"kind": "r2",
"binding": "APP_ASSETS",
"target": null
},
{
"kind": "services",
"binding": "BRAND_API",
"target": null
}
]
},
{
"name": "web",
"kind": "worker",
"directory": "apps/web",
"main": "src/worker.ts",
"worker_name": "topolo-design",
"subdomain": "design",
"healthcheck_path": "/api/health",
"variable_names": [
"INSIGHTS_SITE_KEY"
],
"secret_names": [],
"bindings": [
{
"kind": "services",
"binding": "API",
"target": null
}
]
}
],
"notifications": [
"design.export.ready"
],
"notification_contract": {
"source_path": "topolo.notification-contracts.json",
"role": "producer",
"schema_version": 1,
"owner_app_id": "app_topolo_design",
"events": [
{
"type": "design.export.ready",
"version": 1,
"description": "A persisted Design export reached ready state after its content was stored.",
"status": "published",
"payloadSchema": {
"type": "object",
"required": [
"title",
"body",
"object_id",
"occurred_at",
"project_id",
"export_id",
"format"
],
"properties": {
"title": {
"type": "string",
"minLength": 1
},
"body": {
"type": "string",
"minLength": 1
},
"surface": {
"enum": [
"notification",
"action"
]
},
"priority": {
"enum": [
"low",
"normal",
"high",
"urgent"
]
},
"severity": {
"enum": [
"info",
"success",
"warning",
"critical"
]
},
"category": {
"type": "string"
},
"object_type": {
"type": "string"
},
"object_id": {
"type": "string",
"minLength": 1
},
"cta_url": {
"type": "string",
"format": "uri"
},
"cta_label": {
"type": "string"
},
"occurred_at": {
"type": "string",
"format": "date-time"
},
"project_id": {
"type": "string",
"minLength": 1
},
"export_id": {
"type": "string",
"minLength": 1
},
"format": {
"enum": [
"svg",
"png",
"jpeg",
"mp4"
]
}
},
"additionalProperties": false
},
"examples": [
{
"title": "Export ready: Launch graphic",
"body": "Your PNG export is ready.",
"surface": "action",
"priority": "normal",
"severity": "success",
"category": "design",
"object_type": "design_export",
"object_id": "design_export_123",
"cta_url": "https://design.topolo.app/app/projects/design_123",
"cta_label": "Open design",
"occurred_at": "2026-08-10T00:00:00.000Z",
"project_id": "design_123",
"export_id": "design_export_123",
"format": "png"
}
],
"dataClassification": "internal",
"recipients": {
"modes": [
"workspace_member"
],
"externalAddress": "forbidden"
},
"idempotency": {
"required": true,
"pattern": "^design:export:ready:"
},
"sensitiveFields": []
}
]
},
"actions": [
{
"name": "widget.get",
"title": "Get widget summary",
"description": "Get the TopoloOne widget summary for Design.",
"method": "GET",
"path": "/api/widget",
"permission": "workspace:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"widgets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"appId": {
"type": "string",
"minLength": 1
}
},
"required": [
"appId"
],
"additionalProperties": {}
}
}
},
"required": [
"success",
"widgets"
],
"additionalProperties": {}
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=widget.get",
"resource": {
"kind": "widget",
"idPath": "$.id"
},
"effects": [
"Reads widget data without changing service state."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission workspace:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Validate the response against outputSchema and confirm it belongs to the selected widget context."
],
"examples": [
{
"input": {},
"expected": "A response matching the published outputSchema for widget.get."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/widget",
"body": null
},
"effects": "Reads widget data without changing service state.",
"verification": [
"Validate the response against outputSchema and confirm it belongs to the selected widget context."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission workspace:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=widget.get",
"resource": {
"kind": "widget",
"idPath": "$.id"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/widget",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "workspace.bootstrap",
"title": "Get workspace bootstrap",
"description": "Get the signed Design workspace bootstrap.",
"method": "GET",
"path": "/api/bootstrap",
"permission": "workspace:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"user": {},
"organization": {}
},
"required": [
"user",
"organization"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=workspace.bootstrap",
"resource": {
"kind": "workspace",
"idPath": "$.workspace.id"
},
"effects": [
"Reads the signed Design workspace bootstrap without changing workspace state."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission workspace:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Use the returned workspace id only in the current credential context."
],
"examples": [
{
"input": {},
"expected": "A response matching the published outputSchema for workspace.bootstrap."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_auth.workspaces.list",
"app_topolo_auth.workspaces.create",
"app_topolo_auth.workspaces.rename",
"app_topolo_auth.workspaces.default.set"
]
},
"documentation": {
"example_input": {},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/bootstrap",
"body": null
},
"effects": "Reads the signed Design workspace bootstrap without changing workspace state.",
"verification": [
"Use the returned workspace id only in the current credential context."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission workspace:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=workspace.bootstrap",
"resource": {
"kind": "workspace",
"idPath": "$.workspace.id"
},
"next_action_ids": [
"app_topolo_auth.workspaces.list",
"app_topolo_auth.workspaces.create",
"app_topolo_auth.workspaces.rename",
"app_topolo_auth.workspaces.default.set"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/bootstrap",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "brands.list",
"title": "List Brand options",
"description": "List accessible published Brand kits available for governed design creation.",
"method": "GET",
"path": "/api/brand-options",
"permission": "brands:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"available": {
"type": "boolean"
},
"brands": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"currentVersionId": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"currentVersionId"
],
"additionalProperties": false
}
}
},
"required": [
"available",
"brands"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=brands.list",
"resource": {
"kind": "brand",
"idPath": "$.brands[].id"
},
"effects": [
"Reads brand data without changing service state."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission brands:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Validate the response against outputSchema and confirm it belongs to the selected brand context."
],
"examples": [
{
"input": {},
"expected": "A response matching the published outputSchema for brands.list."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/brand-options",
"body": null
},
"effects": "Reads brand data without changing service state.",
"verification": [
"Validate the response against outputSchema and confirm it belongs to the selected brand context."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission brands:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=brands.list",
"resource": {
"kind": "brand",
"idPath": "$.brands[].id"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/brand-options",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "folders.list",
"title": "List project folders",
"description": "List workspace folders used to catalogue Design projects.",
"method": "GET",
"path": "/api/folders",
"permission": "folders:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"folders": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
}
},
"required": [
"folders"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=folders.list",
"resource": {
"kind": "design_folder",
"idPath": "$.folders[].id"
},
"effects": [
"Reads design_folder data without changing service state."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission folders:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Validate the response against outputSchema and confirm it belongs to the selected design_folder context."
],
"examples": [
{
"input": {},
"expected": "A response matching the published outputSchema for folders.list."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/folders",
"body": null
},
"effects": "Reads design_folder data without changing service state.",
"verification": [
"Validate the response against outputSchema and confirm it belongs to the selected design_folder context."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission folders:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=folders.list",
"resource": {
"kind": "design_folder",
"idPath": "$.folders[].id"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/folders",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "folders.create",
"title": "Create project folder",
"description": "Create a workspace folder for Design projects.",
"method": "POST",
"path": "/api/folders",
"permission": "folders:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 80
}
},
"required": [
"name"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"folder": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"required": [
"folder"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=folders.create",
"resource": {
"kind": "design_folder",
"idPath": "$.folder.id"
},
"effects": [
"Creates one workspace-scoped folder for cataloguing Design projects."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission folders:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.folders.list and confirm the returned folder appears once."
],
"examples": [
{
"input": {
"name": "Launch campaign"
},
"expected": "A response matching the published outputSchema for folders.create."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.folders.delete",
"instructions": "Invoke app_topolo_design.folders.delete with the created folder id after confirming the rollback; any projects already filed into it move to Unfiled."
},
"contractSource": "design-action-metadata",
"rollbackActionId": "app_topolo_design.folders.delete"
},
"documentation": {
"example_input": {
"name": "Launch campaign"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/folders",
"body": {
"name": "Launch campaign"
}
},
"effects": "Creates one workspace-scoped folder for cataloguing Design projects.",
"verification": [
"Call app_topolo_design.folders.list and confirm the returned folder appears once."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.folders.delete",
"instructions": "Invoke app_topolo_design.folders.delete with the created folder id after confirming the rollback; any projects already filed into it move to Unfiled."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission folders:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=folders.create",
"resource": {
"kind": "design_folder",
"idPath": "$.folder.id"
},
"next_action_ids": [],
"rollback_action_id": "app_topolo_design.folders.delete"
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/folders",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "folders.update",
"title": "Rename project folder",
"description": "Rename a workspace folder without changing its projects.",
"method": "PATCH",
"path": "/api/folders/{folderId}",
"permission": "folders:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"folderId": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 80
}
},
"required": [
"folderId",
"name"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"folder": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"required": [
"folder"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=folders.update",
"resource": {
"kind": "design_folder",
"idPath": "$.folder.id"
},
"effects": [
"Rename a workspace folder without changing its projects."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission folders:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Validate the response against outputSchema and confirm it belongs to the selected design_folder context."
],
"examples": [
{
"input": {
"folderId": "design_folder_123",
"name": "Product launch"
},
"expected": "A response matching the published outputSchema for folders.update."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.folders.update",
"requiresSnapshot": true,
"instructions": "Capture the folder name before the call, then invoke this action with the captured name to restore it."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {
"folderId": "design_folder_123",
"name": "Product launch"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "PATCH",
"path": "/api/folders/design_folder_123",
"body": {
"folderId": "design_folder_123",
"name": "Product launch"
}
},
"effects": "Rename a workspace folder without changing its projects.",
"verification": [
"Validate the response against outputSchema and confirm it belongs to the selected design_folder context."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.folders.update",
"requiresSnapshot": true,
"instructions": "Capture the folder name before the call, then invoke this action with the captured name to restore it."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission folders:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=folders.update",
"resource": {
"kind": "design_folder",
"idPath": "$.folder.id"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "declared_unserved",
"route_key": "PATCH /api/folders/*",
"evidence": "No matching served route was extracted from canonical staging source."
}
},
{
"name": "folders.delete",
"title": "Delete project folder",
"description": "Delete a folder and move its projects to Unfiled.",
"method": "DELETE",
"path": "/api/folders/{folderId}",
"permission": "folders:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"folderId": {
"type": "string",
"minLength": 1
}
},
"required": [
"folderId"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"folder": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"required": [
"folder"
],
"additionalProperties": false
},
"target": "api",
"destructive": true,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=folders.delete",
"resource": {
"kind": "design_folder",
"idPath": "$.folder.id"
},
"effects": [
"Deletes one folder and moves its projects to the unfiled collection without deleting projects."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission folders:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.folders.list and confirm the folder is absent, then list projects and confirm their folderId is null."
],
"examples": [
{
"input": {
"folderId": "design_folder_123"
},
"expected": "A response matching the published outputSchema for folders.delete."
}
],
"recovery": {
"mode": "irreversible",
"instructions": "No safe automatic inverse is published. Projects are preserved in Unfiled; recreating the folder does not restore their prior filing, so confirm before calling."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {
"folderId": "design_folder_123"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "DELETE",
"path": "/api/folders/design_folder_123",
"body": null
},
"effects": "Deletes one folder and moves its projects to the unfiled collection without deleting projects.",
"verification": [
"Call app_topolo_design.folders.list and confirm the folder is absent, then list projects and confirm their folderId is null."
],
"recovery": [
{
"mode": "irreversible",
"instructions": "No safe automatic inverse is published. Projects are preserved in Unfiled; recreating the folder does not restore their prior filing, so confirm before calling."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission folders:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=folders.delete",
"resource": {
"kind": "design_folder",
"idPath": "$.folder.id"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "declared_unserved",
"route_key": "DELETE /api/folders/*",
"evidence": "No matching served route was extracted from canonical staging source."
}
},
{
"name": "projects.list",
"title": "List design projects",
"description": "List active, archived, or all design projects in the selected workspace.",
"method": "GET",
"path": "/api/projects",
"permission": "projects:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"scope": {
"default": "active",
"type": "string",
"enum": [
"active",
"archived",
"all"
]
}
},
"required": [
"scope"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"projects": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"status": {
"type": "string",
"enum": [
"draft",
"ready",
"archived"
]
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"starred": {
"type": "boolean"
},
"brandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"brandVersionId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
},
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"pageCount": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"id",
"name",
"status",
"folderId",
"starred",
"brandKitId",
"brandVersionId",
"createdAt",
"updatedAt",
"width",
"height",
"pageCount"
],
"additionalProperties": false
}
}
},
"required": [
"projects"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.list",
"resource": {
"kind": "design_project",
"idPath": "$.projects[].id"
},
"effects": [
"Reads design_project data without changing service state."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission projects:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Validate the response against outputSchema and confirm it belongs to the selected design_project context."
],
"examples": [
{
"input": {
"scope": "active"
},
"expected": "A response matching the published outputSchema for projects.list."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {
"scope": "active"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/projects",
"body": null
},
"effects": "Reads design_project data without changing service state.",
"verification": [
"Validate the response against outputSchema and confirm it belongs to the selected design_project context."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission projects:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.list",
"resource": {
"kind": "design_project",
"idPath": "$.projects[].id"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/projects",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "projects.get",
"title": "Get design project",
"description": "Get one editable, version-locked design project.",
"method": "GET",
"path": "/api/projects/{projectId}",
"permission": "projects:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"projectId": {
"type": "string",
"minLength": 1
}
},
"required": [
"projectId"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"project": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"status": {
"type": "string",
"enum": [
"draft",
"ready",
"archived"
]
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"starred": {
"type": "boolean"
},
"brandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"brandVersionId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"status",
"folderId",
"starred",
"brandKitId",
"brandVersionId",
"document",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"required": [
"project"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.get",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"effects": [
"Reads design_project data without changing service state."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission projects:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Validate the response against outputSchema and confirm it belongs to the selected design_project context."
],
"examples": [
{
"input": {
"projectId": "design_123"
},
"expected": "A response matching the published outputSchema for projects.get."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {
"projectId": "design_123"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/projects/design_123",
"body": null
},
"effects": "Reads design_project data without changing service state.",
"verification": [
"Validate the response against outputSchema and confirm it belongs to the selected design_project context."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission projects:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.get",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/projects/*",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "projects.create",
"title": "Create design project",
"description": "Create an editable composition with an optional published Brand version.",
"method": "POST",
"path": "/api/projects",
"permission": "projects:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"brandKitId": {
"type": "string",
"minLength": 1
},
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"starter": {
"default": "blank",
"type": "string",
"enum": [
"blank",
"brand"
]
}
},
"required": [
"name",
"starter"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"project": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"status": {
"type": "string",
"enum": [
"draft",
"ready",
"archived"
]
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"starred": {
"type": "boolean"
},
"brandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"brandVersionId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"status",
"folderId",
"starred",
"brandKitId",
"brandVersionId",
"document",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"required": [
"project"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.create",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"effects": [
"Creates one editable design project, optionally pinned to an accessible published Brand version."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission projects:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.projects.get with the returned project id and confirm its document and optional Brand provenance."
],
"examples": [
{
"input": {
"name": "Launch banner",
"width": 1080,
"height": 1080,
"starter": "blank"
},
"expected": "A response matching the published outputSchema for projects.create."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.projects.archive",
"instructions": "Invoke app_topolo_design.projects.archive with the created project id after confirming the rollback."
},
"contractSource": "design-action-metadata",
"rollbackActionId": "app_topolo_design.projects.archive",
"nextActionIds": [
"app_topolo_design.projects.get",
"app_topolo_design.exports.create"
]
},
"documentation": {
"example_input": {
"name": "Launch banner",
"width": 1080,
"height": 1080,
"starter": "blank"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/projects",
"body": {
"name": "Launch banner",
"width": 1080,
"height": 1080,
"starter": "blank"
}
},
"effects": "Creates one editable design project, optionally pinned to an accessible published Brand version.",
"verification": [
"Call app_topolo_design.projects.get with the returned project id and confirm its document and optional Brand provenance."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.projects.archive",
"instructions": "Invoke app_topolo_design.projects.archive with the created project id after confirming the rollback."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission projects:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.create",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"next_action_ids": [
"app_topolo_design.projects.get",
"app_topolo_design.exports.create"
],
"rollback_action_id": "app_topolo_design.projects.archive"
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/projects",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "projects.copy",
"title": "Copy design project",
"description": "Create an independent editable draft from an existing project while preserving its document and Brand provenance.",
"method": "POST",
"path": "/api/projects/{projectId}/copy",
"permission": "projects:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"projectId": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
}
},
"required": [
"projectId"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"project": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"status": {
"type": "string",
"enum": [
"draft",
"ready",
"archived"
]
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"starred": {
"type": "boolean"
},
"brandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"brandVersionId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"status",
"folderId",
"starred",
"brandKitId",
"brandVersionId",
"document",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"required": [
"project"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.copy",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"effects": [
"Creates one independent draft project from the source document, preserving its pages, layout, assets, and published Brand provenance without copying exports."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission projects:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.projects.get with the returned project id and confirm the document and Brand provenance match the source project."
],
"examples": [
{
"input": {
"projectId": "design_123",
"name": "Launch banner variation"
},
"expected": "A response matching the published outputSchema for projects.copy."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.projects.archive",
"instructions": "Invoke app_topolo_design.projects.archive with the copied project id after confirming the rollback."
},
"contractSource": "design-action-metadata",
"rollbackActionId": "app_topolo_design.projects.archive",
"nextActionIds": [
"app_topolo_design.projects.get",
"app_topolo_design.projects.update",
"app_topolo_design.exports.create"
]
},
"documentation": {
"example_input": {
"projectId": "design_123",
"name": "Launch banner variation"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/projects/design_123/copy",
"body": {
"projectId": "design_123",
"name": "Launch banner variation"
}
},
"effects": "Creates one independent draft project from the source document, preserving its pages, layout, assets, and published Brand provenance without copying exports.",
"verification": [
"Call app_topolo_design.projects.get with the returned project id and confirm the document and Brand provenance match the source project."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.projects.archive",
"instructions": "Invoke app_topolo_design.projects.archive with the copied project id after confirming the rollback."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission projects:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.copy",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"next_action_ids": [
"app_topolo_design.projects.get",
"app_topolo_design.projects.update",
"app_topolo_design.exports.create"
],
"rollback_action_id": "app_topolo_design.projects.archive"
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/projects/*/copy",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "projects.update",
"title": "Update design project",
"description": "Rename a project and/or replace its canvas document whole. Read the document with projects.get, modify it, and send the complete result back.",
"method": "PATCH",
"path": "/api/projects/{projectId}",
"permission": "projects:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"projectId": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"starred": {
"type": "boolean"
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
}
},
"required": [
"projectId"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"project": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"status": {
"type": "string",
"enum": [
"draft",
"ready",
"archived"
]
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"starred": {
"type": "boolean"
},
"brandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"brandVersionId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"status",
"folderId",
"starred",
"brandKitId",
"brandVersionId",
"document",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"required": [
"project"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.update",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"effects": [
"Renames, files, or stars one design project and/or replaces its entire canvas document with the provided one."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission projects:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.projects.get and confirm the returned name, folder, star, and document match what was sent."
],
"examples": [
{
"input": {
"projectId": "design_123",
"name": "Updated launch banner",
"document": {
"schemaVersion": 5,
"brand": null,
"fontSources": [],
"pages": [
{
"id": "page_1",
"name": "Page 1",
"canvas": {
"width": 1080,
"height": 1080,
"background": "#ffffff"
},
"elements": [
{
"id": "el_headline",
"name": "Headline",
"purpose": "headline",
"type": "text",
"frame": {
"x": 80,
"y": 120,
"width": 920,
"height": 200,
"rotation": 0
},
"opacity": 1,
"hidden": false,
"locked": false,
"text": "Launch day",
"style": {
"fontFamily": "Inter",
"fontSize": 96,
"minFontSize": 48,
"maxFontSize": 96,
"autoFit": true,
"fontWeight": 700,
"lineHeight": 1.1,
"letterSpacing": 0,
"color": "#111111",
"textAlign": "center",
"verticalAlign": "middle"
}
},
{
"id": "el_accent",
"name": "Accent bar",
"purpose": "decoration",
"type": "shape",
"kind": "rectangle",
"frame": {
"x": 80,
"y": 360,
"width": 920,
"height": 12,
"rotation": 0
},
"opacity": 1,
"hidden": false,
"locked": false,
"style": {
"fill": "#3355ff",
"stroke": "#3355ff",
"strokeWidth": 0,
"cornerRadius": 6
}
}
],
"animation": {
"durationMs": 3000,
"fps": 24,
"motions": [
{
"elementId": "el_headline",
"preset": "fade",
"startMs": 0,
"durationMs": 600,
"easing": "ease-out"
}
]
}
}
],
"exportSettings": {
"format": "png",
"scale": 1,
"quality": 0.92,
"transparent": false
}
}
},
"expected": "A response matching the published outputSchema for projects.update."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.projects.update",
"requiresSnapshot": true,
"instructions": "Capture the current project document and metadata before the call, then invoke this action with the captured values to restore them."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.projects.get",
"app_topolo_design.exports.estimate",
"app_topolo_design.exports.create"
]
},
"documentation": {
"example_input": {
"projectId": "design_123",
"name": "Updated launch banner",
"document": {
"schemaVersion": 5,
"brand": null,
"fontSources": [],
"pages": [
{
"id": "page_1",
"name": "Page 1",
"canvas": {
"width": 1080,
"height": 1080,
"background": "#ffffff"
},
"elements": [
{
"id": "el_headline",
"name": "Headline",
"purpose": "headline",
"type": "text",
"frame": {
"x": 80,
"y": 120,
"width": 920,
"height": 200,
"rotation": 0
},
"opacity": 1,
"hidden": false,
"locked": false,
"text": "Launch day",
"style": {
"fontFamily": "Inter",
"fontSize": 96,
"minFontSize": 48,
"maxFontSize": 96,
"autoFit": true,
"fontWeight": 700,
"lineHeight": 1.1,
"letterSpacing": 0,
"color": "#111111",
"textAlign": "center",
"verticalAlign": "middle"
}
},
{
"id": "el_accent",
"name": "Accent bar",
"purpose": "decoration",
"type": "shape",
"kind": "rectangle",
"frame": {
"x": 80,
"y": 360,
"width": 920,
"height": 12,
"rotation": 0
},
"opacity": 1,
"hidden": false,
"locked": false,
"style": {
"fill": "#3355ff",
"stroke": "#3355ff",
"strokeWidth": 0,
"cornerRadius": 6
}
}
],
"animation": {
"durationMs": 3000,
"fps": 24,
"motions": [
{
"elementId": "el_headline",
"preset": "fade",
"startMs": 0,
"durationMs": 600,
"easing": "ease-out"
}
]
}
}
],
"exportSettings": {
"format": "png",
"scale": 1,
"quality": 0.92,
"transparent": false
}
}
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "PATCH",
"path": "/api/projects/design_123",
"body": {
"projectId": "design_123",
"name": "Updated launch banner",
"document": {
"schemaVersion": 5,
"brand": null,
"fontSources": [],
"pages": [
{
"id": "page_1",
"name": "Page 1",
"canvas": {
"width": 1080,
"height": 1080,
"background": "#ffffff"
},
"elements": [
{
"id": "el_headline",
"name": "Headline",
"purpose": "headline",
"type": "text",
"frame": {
"x": 80,
"y": 120,
"width": 920,
"height": 200,
"rotation": 0
},
"opacity": 1,
"hidden": false,
"locked": false,
"text": "Launch day",
"style": {
"fontFamily": "Inter",
"fontSize": 96,
"minFontSize": 48,
"maxFontSize": 96,
"autoFit": true,
"fontWeight": 700,
"lineHeight": 1.1,
"letterSpacing": 0,
"color": "#111111",
"textAlign": "center",
"verticalAlign": "middle"
}
},
{
"id": "el_accent",
"name": "Accent bar",
"purpose": "decoration",
"type": "shape",
"kind": "rectangle",
"frame": {
"x": 80,
"y": 360,
"width": 920,
"height": 12,
"rotation": 0
},
"opacity": 1,
"hidden": false,
"locked": false,
"style": {
"fill": "#3355ff",
"stroke": "#3355ff",
"strokeWidth": 0,
"cornerRadius": 6
}
}
],
"animation": {
"durationMs": 3000,
"fps": 24,
"motions": [
{
"elementId": "el_headline",
"preset": "fade",
"startMs": 0,
"durationMs": 600,
"easing": "ease-out"
}
]
}
}
],
"exportSettings": {
"format": "png",
"scale": 1,
"quality": 0.92,
"transparent": false
}
}
}
},
"effects": "Renames, files, or stars one design project and/or replaces its entire canvas document with the provided one.",
"verification": [
"Call app_topolo_design.projects.get and confirm the returned name, folder, star, and document match what was sent."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.projects.update",
"requiresSnapshot": true,
"instructions": "Capture the current project document and metadata before the call, then invoke this action with the captured values to restore them."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission projects:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.update",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"next_action_ids": [
"app_topolo_design.projects.get",
"app_topolo_design.exports.estimate",
"app_topolo_design.exports.create"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "PATCH /api/projects/*",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "projects.archive",
"title": "Archive design project",
"description": "Archive a design project without deleting its provenance or exports.",
"method": "DELETE",
"path": "/api/projects/{projectId}",
"permission": "projects:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"projectId": {
"type": "string",
"minLength": 1
}
},
"required": [
"projectId"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"project": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"status": {
"type": "string",
"enum": [
"draft",
"ready",
"archived"
]
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"starred": {
"type": "boolean"
},
"brandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"brandVersionId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"status",
"folderId",
"starred",
"brandKitId",
"brandVersionId",
"document",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"required": [
"project"
],
"additionalProperties": false
},
"target": "api",
"destructive": true,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.archive",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"effects": [
"Archives one design project so it no longer appears in the active project list."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission projects:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.projects.get and confirm the returned project status is archived."
],
"examples": [
{
"input": {
"projectId": "design_123"
},
"expected": "A response matching the published outputSchema for projects.archive."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.projects.restore",
"instructions": "Invoke app_topolo_design.projects.restore with the archived project id to return it to the workspace library."
},
"contractSource": "design-action-metadata",
"rollbackActionId": "app_topolo_design.projects.restore"
},
"documentation": {
"example_input": {
"projectId": "design_123"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "DELETE",
"path": "/api/projects/design_123",
"body": null
},
"effects": "Archives one design project so it no longer appears in the active project list.",
"verification": [
"Call app_topolo_design.projects.get and confirm the returned project status is archived."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.projects.restore",
"instructions": "Invoke app_topolo_design.projects.restore with the archived project id to return it to the workspace library."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission projects:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.archive",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"next_action_ids": [],
"rollback_action_id": "app_topolo_design.projects.restore"
},
"implementation": {
"status": "implemented",
"route_key": "DELETE /api/projects/*",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "projects.delete",
"title": "Delete an archived project",
"description": "Permanently remove one archived design project and every export taken from it. Refused unless the project is already archived.",
"method": "DELETE",
"path": "/api/projects/{projectId}/delete",
"permission": "projects:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"projectId": {
"type": "string",
"minLength": 1
}
},
"required": [
"projectId"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"deleted": {
"type": "string"
},
"exports": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"deleted",
"exports"
],
"additionalProperties": false
},
"target": "api",
"destructive": true,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.delete",
"resource": {
"kind": "design_project",
"idPath": "$.deleted"
},
"effects": [
"Permanently removes one archived design project and every export taken from it, including their stored objects.",
"Refused with 409 unless the project is already archived."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission projects:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.projects.list with scope archived and confirm the project id is absent."
],
"examples": [
{
"input": {
"projectId": "design_launch"
},
"expected": "A response matching the published outputSchema for projects.delete."
}
],
"recovery": {
"mode": "irreversible",
"instructions": "Deletion is permanent. Export anything worth keeping before calling, and archive rather than delete when in doubt."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {
"projectId": "design_launch"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "DELETE",
"path": "/api/projects/design_launch/delete",
"body": null
},
"effects": "Permanently removes one archived design project and every export taken from it, including their stored objects. Refused with 409 unless the project is already archived.",
"verification": [
"Call app_topolo_design.projects.list with scope archived and confirm the project id is absent."
],
"recovery": [
{
"mode": "irreversible",
"instructions": "Deletion is permanent. Export anything worth keeping before calling, and archive rather than delete when in doubt."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission projects:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.delete",
"resource": {
"kind": "design_project",
"idPath": "$.deleted"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "DELETE /api/projects/*/delete",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "projects.restore",
"title": "Restore design project",
"description": "Restore an archived design project to the editable draft list.",
"method": "POST",
"path": "/api/projects/{projectId}/restore",
"permission": "projects:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"projectId": {
"type": "string",
"minLength": 1
}
},
"required": [
"projectId"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"project": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"status": {
"type": "string",
"enum": [
"draft",
"ready",
"archived"
]
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"starred": {
"type": "boolean"
},
"brandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"brandVersionId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"status",
"folderId",
"starred",
"brandKitId",
"brandVersionId",
"document",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"required": [
"project"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.restore",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"effects": [
"Restores one archived design project to draft status."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission projects:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.projects.get and confirm the returned project status is draft."
],
"examples": [
{
"input": {
"projectId": "design_123"
},
"expected": "A response matching the published outputSchema for projects.restore."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.projects.archive",
"instructions": "Invoke app_topolo_design.projects.archive with the restored project id to archive it again."
},
"contractSource": "design-action-metadata",
"rollbackActionId": "app_topolo_design.projects.archive"
},
"documentation": {
"example_input": {
"projectId": "design_123"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/projects/design_123/restore",
"body": {
"projectId": "design_123"
}
},
"effects": "Restores one archived design project to draft status.",
"verification": [
"Call app_topolo_design.projects.get and confirm the returned project status is draft."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.projects.archive",
"instructions": "Invoke app_topolo_design.projects.archive with the restored project id to archive it again."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission projects:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=projects.restore",
"resource": {
"kind": "design_project",
"idPath": "$.project.id"
},
"next_action_ids": [],
"rollback_action_id": "app_topolo_design.projects.archive"
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/projects/*/restore",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "exports.list",
"title": "List design exports",
"description": "List ready, pending, or all generated Design exports stored for the selected workspace.",
"method": "GET",
"path": "/api/exports",
"permission": "exports:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"status": {
"default": "ready",
"type": "string",
"enum": [
"ready",
"pending",
"all"
]
}
},
"required": [
"status"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"exports": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"projectId": {
"type": "string",
"minLength": 1
},
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4"
]
},
"mimeType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"video/mp4"
]
},
"width": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"height": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"durationMs": {
"anyOf": [
{
"type": "integer",
"minimum": 500,
"maximum": 30000
},
{
"type": "null"
}
]
},
"fps": {
"anyOf": [
{
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
{
"type": "null"
}
]
},
"storageKey": {
"type": "string",
"minLength": 1
},
"altText": {
"type": "string",
"minLength": 1
},
"estimatedByteSize": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"byteSize": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"pending",
"ready"
]
},
"createdAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"projectId",
"format",
"mimeType",
"width",
"height",
"quality",
"durationMs",
"fps",
"storageKey",
"altText",
"estimatedByteSize",
"byteSize",
"status",
"createdAt"
],
"additionalProperties": false
}
}
},
"required": [
"exports"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.list",
"resource": {
"kind": "design_export",
"idPath": "$.exports[].id"
},
"effects": [
"Lists immutable Design media records stored for the selected workspace without downloading their content."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission exports:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Confirm every returned export belongs to the selected workspace and use exports.get before downloading content."
],
"examples": [
{
"input": {
"status": "ready"
},
"expected": "A response matching the published outputSchema for exports.list."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.exports.get"
]
},
"documentation": {
"example_input": {
"status": "ready"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/exports",
"body": null
},
"effects": "Lists immutable Design media records stored for the selected workspace without downloading their content.",
"verification": [
"Confirm every returned export belongs to the selected workspace and use exports.get before downloading content."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission exports:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.list",
"resource": {
"kind": "design_export",
"idPath": "$.exports[].id"
},
"next_action_ids": [
"app_topolo_design.exports.get"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/exports",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "exports.estimate",
"title": "Estimate design export size",
"description": "Estimate the output size for a static or animated Design export without creating it.",
"method": "POST",
"path": "/api/projects/{projectId}/exports/estimate",
"permission": "exports:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"projectId": {
"type": "string",
"minLength": 1
},
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"width": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"height": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"quality": {
"default": 0.92,
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"pages": {
"default": "first",
"description": "MP4 only. \"all\" exports the whole document as one video, laying every page end to end with each page’s declared transition between them; its length comes from the document, not from durationMs.",
"type": "string",
"enum": [
"first",
"all"
]
}
},
"required": [
"projectId",
"format",
"width",
"height",
"quality",
"pages"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"estimate": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4"
]
},
"width": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"height": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"quality": {
"type": "number"
},
"durationMs": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"fps": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"estimatedByteSize": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"format",
"width",
"height",
"quality",
"estimatedByteSize"
],
"additionalProperties": false
}
},
"required": [
"estimate"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.estimate",
"resource": {
"kind": "design_export_estimate",
"idPath": "$.estimate.estimatedByteSize"
},
"effects": [
"Calculates a deterministic export-size estimate without creating an export or rendering content."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission exports:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Confirm the returned format, dimensions, duration, frame rate, and estimatedByteSize match the requested settings."
],
"examples": [
{
"input": {
"projectId": "design_123",
"format": "png",
"width": 1080,
"height": 1080,
"quality": 0.92,
"pages": "first"
},
"expected": "A response matching the published outputSchema for exports.estimate."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.exports.create"
]
},
"documentation": {
"example_input": {
"projectId": "design_123",
"format": "png",
"width": 1080,
"height": 1080,
"quality": 0.92,
"pages": "first"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "POST",
"path": "/api/projects/design_123/exports/estimate",
"body": {
"projectId": "design_123",
"format": "png",
"width": 1080,
"height": 1080,
"quality": 0.92,
"pages": "first"
}
},
"effects": "Calculates a deterministic export-size estimate without creating an export or rendering content.",
"verification": [
"Confirm the returned format, dimensions, duration, frame rate, and estimatedByteSize match the requested settings."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission exports:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.estimate",
"resource": {
"kind": "design_export_estimate",
"idPath": "$.estimate.estimatedByteSize"
},
"next_action_ids": [
"app_topolo_design.exports.create"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/projects/*/exports/estimate",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "exports.create",
"title": "Create design export",
"description": "Create a design export. SVG, PNG, and JPEG return ready. Short MP4 clips return ready too; longer clips return pending while the service encodes in the background — poll exports.get or await the export-ready notification.",
"method": "POST",
"path": "/api/projects/{projectId}/exports",
"permission": "exports:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"projectId": {
"type": "string",
"minLength": 1
},
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"width": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"height": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"quality": {
"default": 0.92,
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"pages": {
"default": "first",
"description": "MP4 only. \"all\" exports the whole document as one video, laying every page end to end with each page’s declared transition between them; its length comes from the document, not from durationMs.",
"type": "string",
"enum": [
"first",
"all"
]
},
"altText": {
"type": "string",
"minLength": 1,
"maxLength": 500
}
},
"required": [
"projectId",
"format",
"width",
"height",
"quality",
"pages",
"altText"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"export": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"projectId": {
"type": "string",
"minLength": 1
},
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4"
]
},
"mimeType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"video/mp4"
]
},
"width": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"height": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"durationMs": {
"anyOf": [
{
"type": "integer",
"minimum": 500,
"maximum": 30000
},
{
"type": "null"
}
]
},
"fps": {
"anyOf": [
{
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
{
"type": "null"
}
]
},
"storageKey": {
"type": "string",
"minLength": 1
},
"altText": {
"type": "string",
"minLength": 1
},
"estimatedByteSize": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"byteSize": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"pending",
"ready"
]
},
"createdAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"projectId",
"format",
"mimeType",
"width",
"height",
"quality",
"durationMs",
"fps",
"storageKey",
"altText",
"estimatedByteSize",
"byteSize",
"status",
"createdAt"
],
"additionalProperties": false
}
},
"required": [
"export"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.create",
"resource": {
"kind": "design_export",
"idPath": "$.export.id"
},
"effects": [
"Creates an immutable export record. Stills and short clips come back ready; a longer MP4 comes back pending and the service encodes it in the background until exports.get reports ready."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission exports:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.exports.get with the returned export id and confirm its status and dimensions."
],
"examples": [
{
"input": {
"projectId": "design_123",
"format": "png",
"width": 1080,
"height": 1080,
"quality": 0.92,
"pages": "first",
"altText": "Launch announcement"
},
"expected": "A response matching the published outputSchema for exports.create."
}
],
"recovery": {
"mode": "irreversible",
"instructions": "Export records are immutable and additive; no delete or rollback action is published. Unused exports can be left unpublished safely."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.exports.get",
"app_topolo_design.exports.upload",
"app_topolo_design.exports.handoff"
]
},
"documentation": {
"example_input": {
"projectId": "design_123",
"format": "png",
"width": 1080,
"height": 1080,
"quality": 0.92,
"pages": "first",
"altText": "Launch announcement"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/projects/design_123/exports",
"body": {
"projectId": "design_123",
"format": "png",
"width": 1080,
"height": 1080,
"quality": 0.92,
"pages": "first",
"altText": "Launch announcement"
}
},
"effects": "Creates an immutable export record. Stills and short clips come back ready; a longer MP4 comes back pending and the service encodes it in the background until exports.get reports ready.",
"verification": [
"Call app_topolo_design.exports.get with the returned export id and confirm its status and dimensions."
],
"recovery": [
{
"mode": "irreversible",
"instructions": "Export records are immutable and additive; no delete or rollback action is published. Unused exports can be left unpublished safely."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission exports:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.create",
"resource": {
"kind": "design_export",
"idPath": "$.export.id"
},
"next_action_ids": [
"app_topolo_design.exports.get",
"app_topolo_design.exports.upload",
"app_topolo_design.exports.handoff"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/projects/*/exports",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "exports.upload",
"title": "Upload rendered export",
"description": "Upload rendered PNG, JPEG, or short MP4 bytes for an export still pending. The service renders these formats itself, so this is a fallback for content it could not produce.",
"method": "PUT",
"path": "/api/exports/{exportId}/content",
"permission": "exports:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"exportId": {
"type": "string",
"minLength": 1
},
"contentBase64": {
"type": "string",
"minLength": 1,
"maxLength": 34952536,
"pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
},
"contentType": {
"type": "string",
"enum": [
"image/png",
"image/jpeg",
"video/mp4"
]
},
"fileName": {
"type": "string",
"minLength": 1,
"maxLength": 255
}
},
"required": [
"exportId",
"contentBase64",
"contentType",
"fileName"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"export": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"projectId": {
"type": "string",
"minLength": 1
},
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4"
]
},
"mimeType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"video/mp4"
]
},
"width": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"height": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"durationMs": {
"anyOf": [
{
"type": "integer",
"minimum": 500,
"maximum": 30000
},
{
"type": "null"
}
]
},
"fps": {
"anyOf": [
{
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
{
"type": "null"
}
]
},
"storageKey": {
"type": "string",
"minLength": 1
},
"altText": {
"type": "string",
"minLength": 1
},
"estimatedByteSize": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"byteSize": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"pending",
"ready"
]
},
"createdAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"projectId",
"format",
"mimeType",
"width",
"height",
"quality",
"durationMs",
"fps",
"storageKey",
"altText",
"estimatedByteSize",
"byteSize",
"status",
"createdAt"
],
"additionalProperties": false
}
},
"required": [
"export"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.upload",
"resource": {
"kind": "design_export",
"idPath": "$.export.id"
},
"effects": [
"Stores raster or MP4 bytes for one pending export and marks the export ready."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission exports:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.exports.get and confirm the export status is ready and byteSize matches the uploaded content."
],
"examples": [
{
"input": {
"exportId": "export_123",
"contentBase64": "aGVsbG8=",
"contentType": "image/png",
"fileName": "launch.png"
},
"expected": "A response matching the published outputSchema for exports.upload."
}
],
"recovery": {
"mode": "irreversible",
"instructions": "Uploading marks the pending export ready and cannot be undone; create a new export for corrected content."
},
"contractSource": "design-action-metadata",
"upload": {
"profile": "inline-base64",
"contentField": "contentBase64",
"contentTypeField": "contentType",
"fileNameField": "fileName",
"maxBytes": 26214400,
"acceptedContentTypes": [
"image/png",
"image/jpeg",
"video/mp4",
"application/pdf",
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
]
},
"nextActionIds": [
"app_topolo_design.exports.get",
"app_topolo_design.exports.handoff"
]
},
"documentation": {
"example_input": {
"exportId": "export_123",
"contentBase64": "aGVsbG8=",
"contentType": "image/png",
"fileName": "launch.png"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "PUT",
"path": "/api/exports/export_123/content",
"body": {
"exportId": "export_123",
"contentBase64": "aGVsbG8=",
"contentType": "image/png",
"fileName": "launch.png"
}
},
"effects": "Stores raster or MP4 bytes for one pending export and marks the export ready.",
"verification": [
"Call app_topolo_design.exports.get and confirm the export status is ready and byteSize matches the uploaded content."
],
"recovery": [
{
"mode": "irreversible",
"instructions": "Uploading marks the pending export ready and cannot be undone; create a new export for corrected content."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission exports:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.upload",
"resource": {
"kind": "design_export",
"idPath": "$.export.id"
},
"next_action_ids": [
"app_topolo_design.exports.get",
"app_topolo_design.exports.handoff"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "PUT /api/exports/*/content",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "exports.get",
"title": "Get design export",
"description": "Get export metadata and the authenticated content URL for a Design export.",
"method": "GET",
"path": "/api/exports/{exportId}",
"permission": "exports:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"exportId": {
"type": "string",
"minLength": 1
}
},
"required": [
"exportId"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"export": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"projectId": {
"type": "string",
"minLength": 1
},
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4"
]
},
"mimeType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"video/mp4"
]
},
"width": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"height": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"durationMs": {
"anyOf": [
{
"type": "integer",
"minimum": 500,
"maximum": 30000
},
{
"type": "null"
}
]
},
"fps": {
"anyOf": [
{
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
{
"type": "null"
}
]
},
"storageKey": {
"type": "string",
"minLength": 1
},
"altText": {
"type": "string",
"minLength": 1
},
"estimatedByteSize": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"byteSize": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"pending",
"ready"
]
},
"createdAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"projectId",
"format",
"mimeType",
"width",
"height",
"quality",
"durationMs",
"fps",
"storageKey",
"altText",
"estimatedByteSize",
"byteSize",
"status",
"createdAt"
],
"additionalProperties": false
},
"contentUrl": {
"type": "string",
"minLength": 1
}
},
"required": [
"export",
"contentUrl"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.get",
"resource": {
"kind": "design_export",
"idPath": "$.export.id"
},
"effects": [
"Reads design_export data without changing service state."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission exports:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Validate the response against outputSchema and confirm it belongs to the selected design_export context."
],
"examples": [
{
"input": {
"exportId": "export_123"
},
"expected": "A response matching the published outputSchema for exports.get."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {
"exportId": "export_123"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/exports/export_123",
"body": null
},
"effects": "Reads design_export data without changing service state.",
"verification": [
"Validate the response against outputSchema and confirm it belongs to the selected design_export context."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission exports:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.get",
"resource": {
"kind": "design_export",
"idPath": "$.export.id"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/exports/*",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "exports.handoff",
"title": "Create social handoff",
"description": "Create a media descriptor for Social Studio or Socialize from a ready export.",
"method": "POST",
"path": "/api/exports/{exportId}/handoffs",
"permission": "exports:handoff",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"exportId": {
"type": "string",
"minLength": 1
},
"target": {
"type": "string",
"enum": [
"social_studio",
"socialize"
]
},
"externalResourceId": {
"type": "string",
"minLength": 1
}
},
"required": [
"exportId",
"target"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"handoff": {
"type": "object",
"properties": {
"target": {
"type": "string",
"enum": [
"social_studio",
"socialize"
]
},
"externalResourceId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"projectId": {
"type": "string",
"minLength": 1
},
"exportId": {
"type": "string",
"minLength": 1
},
"mediaUrl": {
"type": "string",
"minLength": 1
},
"requiresCredential": {
"type": "boolean"
},
"filename": {
"type": "string",
"minLength": 1
},
"mediaType": {
"type": "string",
"enum": [
"image",
"video"
]
},
"mimeType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"video/mp4"
]
},
"width": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"height": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"durationMs": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"fps": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"byteSize": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"altText": {
"type": "string",
"minLength": 1
}
},
"required": [
"target",
"externalResourceId",
"projectId",
"exportId",
"mediaUrl",
"requiresCredential",
"filename",
"mediaType",
"mimeType",
"width",
"height",
"durationMs",
"fps",
"byteSize",
"altText"
],
"additionalProperties": false
}
},
"required": [
"handoff"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.handoff",
"resource": {
"kind": "design_export",
"idPath": "$.handoff.exportId"
},
"effects": [
"Returns a provenance-preserving media descriptor for a ready export without mutating the target application."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission exports:handoff and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Confirm the descriptor exportId, projectId, MIME type, dimensions, and authenticated content URL match app_topolo_design.exports.get."
],
"examples": [
{
"input": {
"exportId": "export_123",
"target": "socialize"
},
"expected": "A response matching the published outputSchema for exports.handoff."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "Produces a provenance-preserving media descriptor without mutating Design or the target application; discard the descriptor if unused."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_social_studio.assets.upload",
"app_topolo_socialize.media.upload_url.create",
"app_topolo_socialize.media.upload.complete"
]
},
"documentation": {
"example_input": {
"exportId": "export_123",
"target": "socialize"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/exports/export_123/handoffs",
"body": {
"exportId": "export_123",
"target": "socialize"
}
},
"effects": "Returns a provenance-preserving media descriptor for a ready export without mutating the target application.",
"verification": [
"Confirm the descriptor exportId, projectId, MIME type, dimensions, and authenticated content URL match app_topolo_design.exports.get."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "Produces a provenance-preserving media descriptor without mutating Design or the target application; discard the descriptor if unused."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission exports:handoff and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=exports.handoff",
"resource": {
"kind": "design_export",
"idPath": "$.handoff.exportId"
},
"next_action_ids": [
"app_topolo_social_studio.assets.upload",
"app_topolo_socialize.media.upload_url.create",
"app_topolo_socialize.media.upload.complete"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/exports/*/handoffs",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "media.list",
"title": "List uploaded media",
"description": "List reusable source images and videos uploaded to the selected Design workspace.",
"method": "GET",
"path": "/api/media",
"permission": "media:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"cursor": {
"type": "string",
"minLength": 1
},
"limit": {
"default": 48,
"type": "integer",
"minimum": 1,
"maximum": 100
}
},
"required": [
"limit"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"media": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"source": {
"type": "string",
"const": "upload"
},
"name": {
"type": "string",
"minLength": 1
},
"fileName": {
"type": "string",
"minLength": 1
},
"projectId": {
"type": "null"
},
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"webp",
"mp4"
]
},
"mimeType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"image/webp",
"video/mp4"
]
},
"mediaType": {
"type": "string",
"enum": [
"image",
"video"
]
},
"width": {
"type": "null"
},
"height": {
"type": "null"
},
"durationMs": {
"type": "null"
},
"altText": {
"type": "string",
"minLength": 1
},
"byteSize": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"const": "ready"
},
"createdAt": {
"type": "string",
"minLength": 1
},
"contentUrl": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"source",
"name",
"fileName",
"projectId",
"format",
"mimeType",
"mediaType",
"width",
"height",
"durationMs",
"altText",
"byteSize",
"status",
"createdAt",
"contentUrl"
],
"additionalProperties": false
}
},
"nextCursor": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
}
},
"required": [
"media",
"nextCursor"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=media.list",
"resource": {
"kind": "design_media",
"idPath": "$.media[].id"
},
"effects": [
"Lists reusable source media uploaded to the selected Design workspace. Generated exports are intentionally excluded."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission media:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Confirm each returned item is an uploaded source asset in the selected workspace."
],
"examples": [
{
"input": {
"limit": 48
},
"expected": "A response matching the published outputSchema for media.list."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.media.upload",
"app_topolo_design.media.delete"
]
},
"documentation": {
"example_input": {
"limit": 48
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/media",
"body": null
},
"effects": "Lists reusable source media uploaded to the selected Design workspace. Generated exports are intentionally excluded.",
"verification": [
"Confirm each returned item is an uploaded source asset in the selected workspace."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission media:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=media.list",
"resource": {
"kind": "design_media",
"idPath": "$.media[].id"
},
"next_action_ids": [
"app_topolo_design.media.upload",
"app_topolo_design.media.delete"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/media",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "media.upload",
"title": "Upload source media",
"description": "Upload a reusable source image or video to the selected Design workspace Media library.",
"method": "POST",
"path": "/api/media",
"permission": "media:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"contentBase64": {
"type": "string",
"minLength": 1,
"maxLength": 34952536,
"pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
},
"contentType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"image/webp",
"video/mp4"
]
},
"fileName": {
"type": "string",
"minLength": 1,
"maxLength": 255
},
"altText": {
"type": "string",
"maxLength": 500
}
},
"required": [
"contentBase64",
"contentType",
"fileName"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"media": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"source": {
"type": "string",
"const": "upload"
},
"name": {
"type": "string",
"minLength": 1
},
"fileName": {
"type": "string",
"minLength": 1
},
"projectId": {
"type": "null"
},
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"webp",
"mp4"
]
},
"mimeType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"image/webp",
"video/mp4"
]
},
"mediaType": {
"type": "string",
"enum": [
"image",
"video"
]
},
"width": {
"type": "null"
},
"height": {
"type": "null"
},
"durationMs": {
"type": "null"
},
"altText": {
"type": "string",
"minLength": 1
},
"byteSize": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"const": "ready"
},
"createdAt": {
"type": "string",
"minLength": 1
},
"contentUrl": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"source",
"name",
"fileName",
"projectId",
"format",
"mimeType",
"mediaType",
"width",
"height",
"durationMs",
"altText",
"byteSize",
"status",
"createdAt",
"contentUrl"
],
"additionalProperties": false
}
},
"required": [
"media"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=media.upload",
"resource": {
"kind": "design_media",
"idPath": "$.media.id"
},
"effects": [
"Stores one reusable source asset in the selected workspace media library."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission media:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.media.list and confirm the returned id, filename, MIME type, and byte size."
],
"examples": [
{
"input": {
"contentBase64": "aGVsbG8=",
"contentType": "image/png",
"fileName": "launch.png",
"altText": "Launch artwork"
},
"expected": "A response matching the published outputSchema for media.upload."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.media.delete",
"instructions": "Call media.delete with the returned media id if the source asset is not referenced by any design."
},
"contractSource": "design-action-metadata",
"upload": {
"profile": "inline-base64",
"contentField": "contentBase64",
"contentTypeField": "contentType",
"fileNameField": "fileName",
"maxBytes": 26214400,
"acceptedContentTypes": [
"image/svg+xml",
"image/png",
"image/jpeg",
"image/webp",
"video/mp4"
]
},
"nextActionIds": [
"app_topolo_design.media.list",
"app_topolo_design.media.delete"
]
},
"documentation": {
"example_input": {
"contentBase64": "aGVsbG8=",
"contentType": "image/png",
"fileName": "launch.png",
"altText": "Launch artwork"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/media",
"body": {
"contentBase64": "aGVsbG8=",
"contentType": "image/png",
"fileName": "launch.png",
"altText": "Launch artwork"
}
},
"effects": "Stores one reusable source asset in the selected workspace media library.",
"verification": [
"Call app_topolo_design.media.list and confirm the returned id, filename, MIME type, and byte size."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.media.delete",
"instructions": "Call media.delete with the returned media id if the source asset is not referenced by any design."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission media:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=media.upload",
"resource": {
"kind": "design_media",
"idPath": "$.media.id"
},
"next_action_ids": [
"app_topolo_design.media.list",
"app_topolo_design.media.delete"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/media",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "media.generate",
"title": "Generate source media",
"description": "Generate an image through the governed provider gateway and store it in the selected Design workspace.",
"method": "POST",
"path": "/api/media/generate",
"permission": "media:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"prompt": {
"type": "string",
"minLength": 10,
"maxLength": 1000
},
"aspectRatio": {
"type": "string",
"enum": [
"1:1",
"16:9",
"9:16",
"4:3",
"3:4"
]
},
"provider": {
"type": "string",
"enum": [
"openai",
"google",
"xai",
"cloudflare"
]
},
"model": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"sourceAsset": {
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"mimeType": {
"type": "string",
"minLength": 1,
"maxLength": 120
}
},
"required": [
"url"
],
"additionalProperties": false
},
"fileName": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"altText": {
"type": "string",
"minLength": 1,
"maxLength": 500
}
},
"required": [
"prompt"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"media": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"source": {
"type": "string",
"const": "upload"
},
"name": {
"type": "string",
"minLength": 1
},
"fileName": {
"type": "string",
"minLength": 1
},
"projectId": {
"type": "null"
},
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"webp",
"mp4"
]
},
"mimeType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"image/webp",
"video/mp4"
]
},
"mediaType": {
"type": "string",
"enum": [
"image",
"video"
]
},
"width": {
"type": "null"
},
"height": {
"type": "null"
},
"durationMs": {
"type": "null"
},
"altText": {
"type": "string",
"minLength": 1
},
"byteSize": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"status": {
"type": "string",
"const": "ready"
},
"createdAt": {
"type": "string",
"minLength": 1
},
"contentUrl": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"source",
"name",
"fileName",
"projectId",
"format",
"mimeType",
"mediaType",
"width",
"height",
"durationMs",
"altText",
"byteSize",
"status",
"createdAt",
"contentUrl"
],
"additionalProperties": false
},
"generation": {
"type": "object",
"properties": {
"provider": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"model": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
}
},
"required": [
"provider",
"model"
],
"additionalProperties": false
}
},
"required": [
"media",
"generation"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=media.generate",
"resource": {
"kind": "design_media",
"idPath": "$.media.id"
},
"effects": [
"Generates one image through the governed provider gateway and stores it as reusable workspace media."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission media:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.media.list and confirm the generated media id, MIME type, and content URL."
],
"examples": [
{
"input": {
"prompt": "A bold editorial illustration of software removing repetitive work",
"aspectRatio": "4:3"
},
"expected": "A response matching the published outputSchema for media.generate."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.media.delete",
"instructions": "Call media.delete with the returned media id while it remains unreferenced."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.media.list",
"app_topolo_design.projects.update",
"app_topolo_design.media.delete_availability"
]
},
"documentation": {
"example_input": {
"prompt": "A bold editorial illustration of software removing repetitive work",
"aspectRatio": "4:3"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/media/generate",
"body": {
"prompt": "A bold editorial illustration of software removing repetitive work",
"aspectRatio": "4:3"
}
},
"effects": "Generates one image through the governed provider gateway and stores it as reusable workspace media.",
"verification": [
"Call app_topolo_design.media.list and confirm the generated media id, MIME type, and content URL."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.media.delete",
"instructions": "Call media.delete with the returned media id while it remains unreferenced."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission media:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=media.generate",
"resource": {
"kind": "design_media",
"idPath": "$.media.id"
},
"next_action_ids": [
"app_topolo_design.media.list",
"app_topolo_design.projects.update",
"app_topolo_design.media.delete_availability"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/media/generate",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "media.delete_availability",
"title": "Check media deletion",
"description": "Check whether a source asset is unreferenced and safe to delete.",
"method": "GET",
"path": "/api/media/{mediaId}/deletion",
"permission": "media:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"mediaId": {
"type": "string",
"minLength": 1
}
},
"required": [
"mediaId"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"allowed": {
"type": "boolean"
},
"reason": {
"type": "string",
"minLength": 1
}
},
"required": [
"allowed"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=media.delete_availability",
"resource": {
"kind": "design_media",
"idPath": "$.allowed"
},
"effects": [
"Checks whether workspace media is unreferenced and therefore safe to delete without changing it."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission media:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Treat allowed false and its reason as authoritative; do not call media.delete until allowed is true."
],
"examples": [
{
"input": {
"mediaId": "design_media_123"
},
"expected": "A response matching the published outputSchema for media.delete_availability."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.media.delete"
]
},
"documentation": {
"example_input": {
"mediaId": "design_media_123"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/media/design_media_123/deletion",
"body": null
},
"effects": "Checks whether workspace media is unreferenced and therefore safe to delete without changing it.",
"verification": [
"Treat allowed false and its reason as authoritative; do not call media.delete until allowed is true."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission media:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=media.delete_availability",
"resource": {
"kind": "design_media",
"idPath": "$.allowed"
},
"next_action_ids": [
"app_topolo_design.media.delete"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/media/*/deletion",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "media.delete",
"title": "Delete source media",
"description": "Permanently delete an unreferenced source asset from the selected Design workspace Media library.",
"method": "DELETE",
"path": "/api/media/{mediaId}",
"permission": "media:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"mediaId": {
"type": "string",
"minLength": 1
}
},
"required": [
"mediaId"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"deleted": {
"type": "boolean",
"const": true
},
"mediaId": {
"type": "string",
"minLength": 1
}
},
"required": [
"deleted",
"mediaId"
],
"additionalProperties": false
},
"target": "api",
"destructive": true,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=media.delete",
"resource": {
"kind": "design_media",
"idPath": "$.mediaId"
},
"effects": [
"Permanently removes one unreferenced source asset from the selected workspace media library."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission media:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.media.list and confirm the deleted media id is absent."
],
"examples": [
{
"input": {
"mediaId": "design_media_123"
},
"expected": "A response matching the published outputSchema for media.delete."
}
],
"recovery": {
"mode": "irreversible",
"instructions": "Deletion is permanent. Upload the source file again if it is needed later."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {
"mediaId": "design_media_123"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "DELETE",
"path": "/api/media/design_media_123",
"body": null
},
"effects": "Permanently removes one unreferenced source asset from the selected workspace media library.",
"verification": [
"Call app_topolo_design.media.list and confirm the deleted media id is absent."
],
"recovery": [
{
"mode": "irreversible",
"instructions": "Deletion is permanent. Upload the source file again if it is needed later."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission media:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=media.delete",
"resource": {
"kind": "design_media",
"idPath": "$.mediaId"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "DELETE /api/media/*",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "fonts.list",
"title": "List workspace fonts",
"description": "List uploaded workspace fonts and their authenticated content URLs.",
"method": "GET",
"path": "/api/fonts",
"permission": "fonts:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"fonts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"family": {
"type": "string",
"minLength": 1
},
"source": {
"type": "string",
"const": "workspace"
},
"contentType": {
"type": "string",
"enum": [
"font/woff2",
"font/woff",
"application/font-woff",
"font/ttf",
"application/x-font-ttf",
"font/otf",
"application/x-font-opentype"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
},
"contentUrl": {
"type": "string",
"minLength": 1
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
}
},
"required": [
"id",
"family",
"source",
"contentType",
"format",
"contentUrl"
],
"additionalProperties": false
}
}
},
"required": [
"fonts"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=fonts.list",
"resource": {
"kind": "design_font",
"idPath": "$.fonts[].id"
},
"effects": [
"Lists workspace font assets with authenticated content URLs for use in Design documents."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission fonts:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Confirm each font belongs to the selected workspace and has a supported content type and format."
],
"examples": [
{
"input": {},
"expected": "A response matching the published outputSchema for fonts.list."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.fonts.upload",
"app_topolo_design.projects.update"
]
},
"documentation": {
"example_input": {},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/fonts",
"body": null
},
"effects": "Lists workspace font assets with authenticated content URLs for use in Design documents.",
"verification": [
"Confirm each font belongs to the selected workspace and has a supported content type and format."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission fonts:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=fonts.list",
"resource": {
"kind": "design_font",
"idPath": "$.fonts[].id"
},
"next_action_ids": [
"app_topolo_design.fonts.upload",
"app_topolo_design.projects.update"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/fonts",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "fonts.upload",
"title": "Upload workspace font",
"description": "Upload one licensed font file for use in Design documents.",
"method": "POST",
"path": "/api/fonts",
"permission": "fonts:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"fileName": {
"type": "string",
"minLength": 1,
"maxLength": 240
},
"contentType": {
"type": "string",
"enum": [
"font/woff2",
"font/woff",
"application/font-woff",
"font/ttf",
"application/x-font-ttf",
"font/otf",
"application/x-font-opentype"
]
},
"contentBase64": {
"type": "string",
"minLength": 1,
"maxLength": 2796204,
"pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
},
"license": {
"type": "string",
"minLength": 1,
"maxLength": 240
}
},
"required": [
"family",
"fileName",
"contentType",
"contentBase64",
"license"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"font": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"family": {
"type": "string",
"minLength": 1
},
"source": {
"type": "string",
"const": "workspace"
},
"contentType": {
"type": "string",
"enum": [
"font/woff2",
"font/woff",
"application/font-woff",
"font/ttf",
"application/x-font-ttf",
"font/otf",
"application/x-font-opentype"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
},
"contentUrl": {
"type": "string",
"minLength": 1
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
}
},
"required": [
"id",
"family",
"source",
"contentType",
"format",
"sourceUrl"
],
"additionalProperties": false
}
},
"required": [
"font"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=fonts.upload",
"resource": {
"kind": "design_font",
"idPath": "$.font.id"
},
"effects": [
"Stores one licensed font file in the selected Design workspace and returns a document-ready embedded source URL."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission fonts:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.fonts.list and confirm the returned font id, family, content type, and format."
],
"examples": [
{
"input": {
"family": "Acme Sans",
"fileName": "acme.woff2",
"contentType": "font/woff2",
"contentBase64": "Zm9udA==",
"license": "Company licence"
},
"expected": "A response matching the published outputSchema for fonts.upload."
}
],
"recovery": {
"mode": "irreversible",
"instructions": "No font deletion contract exists because projects can embed the returned source. Upload only licensed files intended for this workspace."
},
"contractSource": "design-action-metadata",
"upload": {
"profile": "inline-base64",
"contentField": "contentBase64",
"contentTypeField": "contentType",
"fileNameField": "fileName",
"maxBytes": 2097152,
"acceptedContentTypes": [
"font/woff2",
"font/woff",
"application/font-woff",
"font/ttf",
"application/x-font-ttf",
"font/otf",
"application/x-font-opentype"
]
},
"nextActionIds": [
"app_topolo_design.fonts.list",
"app_topolo_design.projects.update"
]
},
"documentation": {
"example_input": {
"family": "Acme Sans",
"fileName": "acme.woff2",
"contentType": "font/woff2",
"contentBase64": "Zm9udA==",
"license": "Company licence"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/fonts",
"body": {
"family": "Acme Sans",
"fileName": "acme.woff2",
"contentType": "font/woff2",
"contentBase64": "Zm9udA==",
"license": "Company licence"
}
},
"effects": "Stores one licensed font file in the selected Design workspace and returns a document-ready embedded source URL.",
"verification": [
"Call app_topolo_design.fonts.list and confirm the returned font id, family, content type, and format."
],
"recovery": [
{
"mode": "irreversible",
"instructions": "No font deletion contract exists because projects can embed the returned source. Upload only licensed files intended for this workspace."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission fonts:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=fonts.upload",
"resource": {
"kind": "design_font",
"idPath": "$.font.id"
},
"next_action_ids": [
"app_topolo_design.fonts.list",
"app_topolo_design.projects.update"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/fonts",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "stock.list",
"title": "List stock images",
"description": "List the shared searchable Design stock image collection.",
"method": "GET",
"path": "/api/stock",
"permission": "workspace:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"stock": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"title": {
"type": "string",
"minLength": 1
},
"tags": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"orientation": {
"type": "string",
"enum": [
"portrait",
"landscape",
"square"
]
},
"altText": {
"type": "string",
"minLength": 1
},
"contentUrl": {
"type": "string",
"minLength": 1
}
},
"required": [
"name",
"title",
"tags",
"orientation",
"altText",
"contentUrl"
],
"additionalProperties": false
}
}
},
"required": [
"stock"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=stock.list",
"resource": {
"kind": "design_stock",
"idPath": "$.stock[].name"
},
"effects": [
"Lists the shared Design stock collection with searchable metadata and public immutable content paths."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission workspace:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Confirm each returned stock name is a safe collection entry before using /api/stock/{name}."
],
"examples": [
{
"input": {},
"expected": "A response matching the published outputSchema for stock.list."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.projects.update"
]
},
"documentation": {
"example_input": {},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/stock",
"body": null
},
"effects": "Lists the shared Design stock collection with searchable metadata and public immutable content paths.",
"verification": [
"Confirm each returned stock name is a safe collection entry before using /api/stock/{name}."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission workspace:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=stock.list",
"resource": {
"kind": "design_stock",
"idPath": "$.stock[].name"
},
"next_action_ids": [
"app_topolo_design.projects.update"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/stock",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "stock.upload",
"title": "Upload stock image",
"description": "Add an approved image to the immutable stock collection shared by every Design workspace.",
"method": "POST",
"path": "/api/stock",
"permission": "library:publish",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"contentBase64": {
"type": "string",
"minLength": 1,
"maxLength": 13981016,
"pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
},
"contentType": {
"type": "string",
"enum": [
"image/png",
"image/jpeg",
"image/webp"
]
},
"fileName": {
"type": "string",
"minLength": 1,
"maxLength": 240
},
"altText": {
"type": "string",
"minLength": 1,
"maxLength": 500
}
},
"required": [
"contentBase64",
"contentType",
"fileName"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"stock": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"title": {
"type": "string",
"minLength": 1
},
"tags": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"orientation": {
"type": "string",
"enum": [
"portrait",
"landscape",
"square"
]
},
"altText": {
"type": "string",
"minLength": 1
},
"contentUrl": {
"type": "string",
"minLength": 1
}
},
"required": [
"name",
"title",
"tags",
"orientation",
"altText",
"contentUrl"
],
"additionalProperties": false
},
"byteSize": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"stock",
"byteSize"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=stock.upload",
"resource": {
"kind": "design_stock",
"idPath": "$.stock.name"
},
"effects": [
"Adds one content-addressed image to the immutable stock collection shared by every Design workspace."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission library:publish and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.stock.list and confirm the returned content-addressed stock name and metadata are present."
],
"examples": [
{
"input": {
"contentBase64": "aGVsbG8=",
"contentType": "image/png",
"fileName": "shared-table.png",
"altText": "A shared table of dishes."
},
"expected": "A response matching the published outputSchema for stock.upload."
}
],
"recovery": {
"mode": "irreversible",
"instructions": "No stock-retirement action exists. Upload only images approved for the shared Design stock collection."
},
"contractSource": "design-action-metadata",
"upload": {
"profile": "inline-base64",
"contentField": "contentBase64",
"contentTypeField": "contentType",
"fileNameField": "fileName",
"maxBytes": 10485760,
"acceptedContentTypes": [
"image/png",
"image/jpeg",
"image/webp"
]
},
"nextActionIds": [
"app_topolo_design.stock.list",
"app_topolo_design.projects.update"
]
},
"documentation": {
"example_input": {
"contentBase64": "aGVsbG8=",
"contentType": "image/png",
"fileName": "shared-table.png",
"altText": "A shared table of dishes."
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/stock",
"body": {
"contentBase64": "aGVsbG8=",
"contentType": "image/png",
"fileName": "shared-table.png",
"altText": "A shared table of dishes."
}
},
"effects": "Adds one content-addressed image to the immutable stock collection shared by every Design workspace.",
"verification": [
"Call app_topolo_design.stock.list and confirm the returned content-addressed stock name and metadata are present."
],
"recovery": [
{
"mode": "irreversible",
"instructions": "No stock-retirement action exists. Upload only images approved for the shared Design stock collection."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission library:publish and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=stock.upload",
"resource": {
"kind": "design_stock",
"idPath": "$.stock.name"
},
"next_action_ids": [
"app_topolo_design.stock.list",
"app_topolo_design.projects.update"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/stock",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "settings.get",
"title": "Get Design settings",
"description": "Get workspace canvas, Brand, export, and motion defaults for Design.",
"method": "GET",
"path": "/api/settings",
"permission": "settings:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"settings": {
"type": "object",
"properties": {
"defaultBrandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"defaultCanvasWidth": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"defaultCanvasHeight": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"defaultExportFormat": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4"
]
},
"defaultExportScale": {
"type": "number"
},
"defaultExportQuality": {
"type": "number"
},
"defaultExportTransparent": {
"type": "boolean"
},
"defaultAnimationDurationMs": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"defaultAnimationFps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
}
},
"required": [
"defaultBrandKitId",
"defaultCanvasWidth",
"defaultCanvasHeight",
"defaultExportFormat",
"defaultExportScale",
"defaultExportQuality",
"defaultExportTransparent",
"defaultAnimationDurationMs",
"defaultAnimationFps"
],
"additionalProperties": false
}
},
"required": [
"settings"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=settings.get",
"resource": {
"kind": "workspace",
"idPath": "$.settings.defaultCanvasWidth"
},
"effects": [
"Reads workspace data without changing service state."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission settings:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Validate the response against outputSchema and confirm it belongs to the selected workspace context."
],
"examples": [
{
"input": {},
"expected": "A response matching the published outputSchema for settings.get."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/settings",
"body": null
},
"effects": "Reads workspace data without changing service state.",
"verification": [
"Validate the response against outputSchema and confirm it belongs to the selected workspace context."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission settings:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=settings.get",
"resource": {
"kind": "workspace",
"idPath": "$.settings.defaultCanvasWidth"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/settings",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "settings.update",
"title": "Update Design settings",
"description": "Update workspace canvas, Brand, export, or motion defaults for Design.",
"method": "PATCH",
"path": "/api/settings",
"permission": "settings:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"defaultBrandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"defaultCanvasWidth": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"defaultCanvasHeight": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"defaultExportFormat": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"defaultExportScale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"defaultExportQuality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"defaultExportTransparent": {
"type": "boolean"
},
"defaultAnimationDurationMs": {
"type": "integer",
"minimum": 1500,
"maximum": 30000
},
"defaultAnimationFps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
}
},
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"settings": {
"type": "object",
"properties": {
"defaultBrandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"defaultCanvasWidth": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"defaultCanvasHeight": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"defaultExportFormat": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4"
]
},
"defaultExportScale": {
"type": "number"
},
"defaultExportQuality": {
"type": "number"
},
"defaultExportTransparent": {
"type": "boolean"
},
"defaultAnimationDurationMs": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"defaultAnimationFps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
}
},
"required": [
"defaultBrandKitId",
"defaultCanvasWidth",
"defaultCanvasHeight",
"defaultExportFormat",
"defaultExportScale",
"defaultExportQuality",
"defaultExportTransparent",
"defaultAnimationDurationMs",
"defaultAnimationFps"
],
"additionalProperties": false
}
},
"required": [
"settings"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=settings.update",
"resource": {
"kind": "workspace",
"idPath": "$.settings.defaultCanvasWidth"
},
"effects": [
"Updates workspace defaults used when new Design projects are created."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission settings:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.settings.get and confirm the persisted defaults match the request."
],
"examples": [
{
"input": {
"defaultBrandKitId": "brand_123",
"defaultCanvasWidth": 1080,
"defaultCanvasHeight": 1350,
"defaultExportFormat": "png"
},
"expected": "A response matching the published outputSchema for settings.update."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.settings.update",
"requiresSnapshot": true,
"instructions": "Capture settings.get before updating, then call settings.update with the prior values to restore them."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {
"defaultBrandKitId": "brand_123",
"defaultCanvasWidth": 1080,
"defaultCanvasHeight": 1350,
"defaultExportFormat": "png"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "PATCH",
"path": "/api/settings",
"body": {
"defaultBrandKitId": "brand_123",
"defaultCanvasWidth": 1080,
"defaultCanvasHeight": 1350,
"defaultExportFormat": "png"
}
},
"effects": "Updates workspace defaults used when new Design projects are created.",
"verification": [
"Call app_topolo_design.settings.get and confirm the persisted defaults match the request."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.settings.update",
"requiresSnapshot": true,
"instructions": "Capture settings.get before updating, then call settings.update with the prior values to restore them."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission settings:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=settings.update",
"resource": {
"kind": "workspace",
"idPath": "$.settings.defaultCanvasWidth"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "PATCH /api/settings",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "privacy.export",
"title": "Export workspace data",
"description": "Export Design projects, uploaded media metadata, generated export metadata, and settings for the selected workspace.",
"method": "GET",
"path": "/api/privacy/export",
"permission": "privacy:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"projects": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"status": {
"type": "string",
"enum": [
"draft",
"ready",
"archived"
]
},
"folderId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"starred": {
"type": "boolean"
},
"brandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"brandVersionId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
},
"createdAt": {
"type": "string",
"minLength": 1
},
"updatedAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"name",
"status",
"folderId",
"starred",
"brandKitId",
"brandVersionId",
"document",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"exports": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"projectId": {
"type": "string",
"minLength": 1
},
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4"
]
},
"mimeType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"video/mp4"
]
},
"width": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"height": {
"type": "integer",
"minimum": 320,
"maximum": 4096
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"durationMs": {
"anyOf": [
{
"type": "integer",
"minimum": 500,
"maximum": 30000
},
{
"type": "null"
}
]
},
"fps": {
"anyOf": [
{
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
{
"type": "null"
}
]
},
"storageKey": {
"type": "string",
"minLength": 1
},
"altText": {
"type": "string",
"minLength": 1
},
"estimatedByteSize": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"byteSize": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"pending",
"ready"
]
},
"createdAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"projectId",
"format",
"mimeType",
"width",
"height",
"quality",
"durationMs",
"fps",
"storageKey",
"altText",
"estimatedByteSize",
"byteSize",
"status",
"createdAt"
],
"additionalProperties": false
}
},
"media": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"fileName": {
"type": "string",
"minLength": 1
},
"mimeType": {
"type": "string",
"enum": [
"image/svg+xml",
"image/png",
"image/jpeg",
"image/webp",
"video/mp4"
]
},
"mediaType": {
"type": "string",
"enum": [
"image",
"video"
]
},
"storageKey": {
"type": "string",
"minLength": 1
},
"altText": {
"type": "string",
"minLength": 1
},
"byteSize": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"createdAt": {
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"fileName",
"mimeType",
"mediaType",
"storageKey",
"altText",
"byteSize",
"createdAt"
],
"additionalProperties": false
}
},
"settings": {
"type": "object",
"properties": {
"defaultBrandKitId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"defaultCanvasWidth": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"defaultCanvasHeight": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"defaultExportFormat": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4"
]
},
"defaultExportScale": {
"type": "number"
},
"defaultExportQuality": {
"type": "number"
},
"defaultExportTransparent": {
"type": "boolean"
},
"defaultAnimationDurationMs": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"defaultAnimationFps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
}
},
"required": [
"defaultBrandKitId",
"defaultCanvasWidth",
"defaultCanvasHeight",
"defaultExportFormat",
"defaultExportScale",
"defaultExportQuality",
"defaultExportTransparent",
"defaultAnimationDurationMs",
"defaultAnimationFps"
],
"additionalProperties": false
}
},
"required": [
"projects",
"exports",
"media",
"settings"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=privacy.export",
"resource": {
"kind": "workspace",
"idPath": "$.workspaceId"
},
"effects": [
"Reads workspace data without changing service state."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission privacy:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Validate the response against outputSchema and confirm it belongs to the selected workspace context."
],
"examples": [
{
"input": {},
"expected": "A response matching the published outputSchema for privacy.export."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/privacy/export",
"body": null
},
"effects": "Reads workspace data without changing service state.",
"verification": [
"Validate the response against outputSchema and confirm it belongs to the selected workspace context."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission privacy:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=privacy.export",
"resource": {
"kind": "workspace",
"idPath": "$.workspaceId"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/privacy/export",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "library.list",
"title": "List starter library templates",
"description": "List one page of the starter templates published to every workspace. Returns card metadata without documents; needs no workspace of its own.",
"method": "GET",
"path": "/api/templates",
"permission": "library:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"cursor": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 60
},
"category": {
"type": "string",
"enum": [
"Social",
"Presentations",
"Documents",
"Marketing",
"Print"
]
},
"style": {
"type": "string",
"enum": [
"Bold",
"Minimal",
"Editorial",
"Playful",
"Professional"
]
},
"q": {
"type": "string",
"minLength": 1,
"maxLength": 120
}
},
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"templates": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"category": {
"type": "string"
},
"style": {
"type": "string"
},
"width": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"height": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"pageCount": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"updatedAt": {
"type": "string"
}
},
"required": [
"id",
"name",
"description",
"category",
"style",
"width",
"height",
"pageCount",
"updatedAt"
],
"additionalProperties": false
}
},
"total": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"required": [
"templates",
"total",
"nextCursor"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=library.list",
"resource": {
"kind": "design_library_template",
"idPath": "$.templates[].id"
},
"effects": [
"Reads one page of the starter library, which is shared by every workspace and needs none.",
"Returns card metadata without documents; pass the returned nextCursor to read the following page."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission library:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Confirm the returned page count matches the requested limit and that nextCursor is null on the last page."
],
"examples": [
{
"input": {
"limit": 12,
"category": "Social"
},
"expected": "A response matching the published outputSchema for library.list."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.library.get",
"app_topolo_design.projects.create"
]
},
"documentation": {
"example_input": {
"limit": 12,
"category": "Social"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/templates",
"body": null
},
"effects": "Reads one page of the starter library, which is shared by every workspace and needs none. Returns card metadata without documents; pass the returned nextCursor to read the following page.",
"verification": [
"Confirm the returned page count matches the requested limit and that nextCursor is null on the last page."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission library:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=library.list",
"resource": {
"kind": "design_library_template",
"idPath": "$.templates[].id"
},
"next_action_ids": [
"app_topolo_design.library.get",
"app_topolo_design.projects.create"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/templates",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "library.get",
"title": "Read one starter library template",
"description": "Read one starter-library template including its full design document. Needs no workspace of its own.",
"method": "GET",
"path": "/api/templates/{id}",
"permission": "library:read",
"readOnly": true,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
}
},
"required": [
"id"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"template": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"category": {
"type": "string"
},
"style": {
"type": "string"
},
"width": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"height": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"pageCount": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"updatedAt": {
"type": "string"
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
}
},
"required": [
"id",
"name",
"description",
"category",
"style",
"width",
"height",
"pageCount",
"updatedAt",
"document"
],
"additionalProperties": false
}
},
"required": [
"template"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": false,
"agentAccess": "auto",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=library.get",
"resource": {
"kind": "design_library_template",
"idPath": "$.template.id"
},
"effects": [
"Reads one starter-library template including its full design document."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission library:read and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Confirm the returned document carries at least one page and the id matches the request."
],
"examples": [
{
"input": {
"id": "after-hours-launch"
},
"expected": "A response matching the published outputSchema for library.get."
}
],
"recovery": {
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.projects.create"
]
},
"documentation": {
"example_input": {
"id": "after-hours-launch"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --json"
],
"http_example": {
"method": "GET",
"path": "/api/templates/after-hours-launch",
"body": null
},
"effects": "Reads one starter-library template including its full design document.",
"verification": [
"Confirm the returned document carries at least one page and the id matches the request."
],
"recovery": [
{
"mode": "not_applicable",
"instructions": "This action does not change service state."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission library:read and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=library.get",
"resource": {
"kind": "design_library_template",
"idPath": "$.template.id"
},
"next_action_ids": [
"app_topolo_design.projects.create"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "GET /api/templates/*",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "library.publish",
"title": "Publish a library template",
"description": "Publish a design into the starter library shared by every workspace, or replace the one already published under this id. Only the organization that owns Design may call this.",
"method": "POST",
"path": "/api/templates",
"permission": "library:publish",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"summary": {
"default": "",
"type": "string",
"maxLength": 280
},
"category": {
"default": "Documents",
"type": "string",
"enum": [
"Social",
"Presentations",
"Documents",
"Marketing",
"Print"
]
},
"style": {
"default": "Minimal",
"type": "string",
"enum": [
"Bold",
"Minimal",
"Editorial",
"Playful",
"Professional"
]
},
"rank": {
"default": 0,
"type": "integer",
"minimum": 0,
"maximum": 9999
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
}
},
"required": [
"id",
"name",
"summary",
"category",
"style",
"rank",
"document"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"template": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"category": {
"type": "string"
},
"style": {
"type": "string"
},
"width": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"height": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"pageCount": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"updatedAt": {
"type": "string"
},
"document": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "number",
"const": 5
},
"brand": {
"anyOf": [
{
"type": "object",
"properties": {
"kitId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"versionId": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"primary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"secondary": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"accent": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"foreground": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"headingFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"bodyFont": {
"type": "string",
"minLength": 1,
"maxLength": 280
},
"logoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedLogoUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"markUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"reversedMarkUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
},
"lockupUrl": {
"anyOf": [
{
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
{
"type": "null"
}
]
}
},
"required": [
"kitId",
"versionId",
"name",
"primary",
"secondary",
"accent",
"background",
"foreground",
"headingFont",
"bodyFont",
"logoUrl",
"reversedLogoUrl",
"markUrl",
"reversedMarkUrl",
"lockupUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"fontSources": {
"maxItems": 4,
"type": "array",
"items": {
"type": "object",
"properties": {
"family": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"type": "string",
"pattern": "^data:[^;,]+;base64,[A-Za-z0-9+/]+={0,2}$"
},
"weight": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 900
},
{
"type": "string",
"pattern": "^\\d{3} \\d{3}$"
}
]
},
"style": {
"type": "string",
"enum": [
"normal",
"italic"
]
},
"format": {
"type": "string",
"enum": [
"woff2",
"woff",
"truetype",
"opentype"
]
}
},
"required": [
"family",
"sourceUrl",
"weight"
],
"additionalProperties": false
}
},
"pages": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"transition": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-left",
"slide-right",
"slide-up",
"slide-down"
]
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 5000
}
},
"required": [
"preset",
"durationMs"
],
"additionalProperties": false,
"description": "How this page arrives from the one before it when the document is exported as one video. The first page has nothing to arrive from, so it cannot carry one; a page without a transition cuts straight in."
},
"canvas": {
"type": "object",
"properties": {
"width": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"height": {
"type": "integer",
"minimum": 64,
"maximum": 8192
},
"background": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"backgroundImage": {
"type": "object",
"properties": {
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
},
"required": [
"width",
"height",
"background"
],
"additionalProperties": false
},
"elements": {
"maxItems": 500,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "text"
},
"text": {
"type": "string",
"maxLength": 10000
},
"style": {
"type": "object",
"properties": {
"fontFamily": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"fontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"minFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"maxFontSize": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1024
},
"autoFit": {
"type": "boolean"
},
"fontWeight": {
"type": "integer",
"minimum": 100,
"maximum": 900
},
"lineHeight": {
"type": "number",
"minimum": 0.5,
"maximum": 4
},
"letterSpacing": {
"type": "number",
"minimum": -100,
"maximum": 500
},
"color": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"textAlign": {
"type": "string",
"enum": [
"left",
"center",
"right"
]
},
"verticalAlign": {
"type": "string",
"enum": [
"top",
"middle",
"bottom"
]
}
},
"required": [
"fontFamily",
"fontSize",
"minFontSize",
"maxFontSize",
"autoFit",
"fontWeight",
"lineHeight",
"letterSpacing",
"color",
"textAlign",
"verticalAlign"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"text",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "shape"
},
"kind": {
"default": "rectangle",
"type": "string",
"enum": [
"rectangle",
"circle",
"ellipse",
"triangle",
"line"
]
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"stroke": {
"type": "string",
"pattern": "^#[0-9a-fA-F]{6}$"
},
"strokeWidth": {
"type": "number",
"minimum": 0,
"maximum": 512
},
"cornerRadius": {
"type": "number",
"minimum": 0,
"maximum": 4096
}
},
"required": [
"fill",
"stroke",
"strokeWidth",
"cornerRadius"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"kind",
"style"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"groupId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"purpose": {
"type": "string",
"maxLength": 120
},
"frame": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 8192
},
"rotation": {
"type": "number",
"minimum": -360,
"maximum": 360
}
},
"required": [
"x",
"y",
"width",
"height",
"rotation"
],
"additionalProperties": false,
"description": "Element placement in canvas pixels. x/y is the top-left corner relative to the canvas origin (top-left); rotation is degrees clockwise."
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"hidden": {
"type": "boolean"
},
"locked": {
"type": "boolean"
},
"type": {
"type": "string",
"const": "image"
},
"mediaAssetId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"sourceUrl": {
"anyOf": [
{
"type": "string",
"const": ""
},
{
"type": "string",
"format": "uri"
}
]
},
"altText": {
"type": "string",
"maxLength": 500
},
"fit": {
"type": "string",
"enum": [
"cover",
"contain",
"fill"
]
}
},
"required": [
"id",
"name",
"purpose",
"frame",
"opacity",
"hidden",
"locked",
"type",
"sourceUrl",
"altText",
"fit"
],
"additionalProperties": false
}
]
},
"description": "Layered page content painted in array order (later elements render on top)."
},
"animation": {
"type": "object",
"properties": {
"durationMs": {
"type": "integer",
"minimum": 500,
"maximum": 30000
},
"fps": {
"anyOf": [
{
"type": "number",
"const": 12
},
{
"type": "number",
"const": 24
},
{
"type": "number",
"const": 30
}
]
},
"motions": {
"maxItems": 500,
"type": "array",
"items": {
"type": "object",
"properties": {
"elementId": {
"type": "string",
"minLength": 1,
"maxLength": 160
},
"preset": {
"type": "string",
"enum": [
"none",
"fade",
"slide-up",
"slide-left",
"zoom-in",
"pulse"
],
"description": "How the layer enters. Use \"none\" to hold the layer from the first frame and give it an exit only."
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
},
"exit": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": [
"fade",
"slide-up",
"slide-down",
"slide-left",
"slide-right",
"zoom-out"
]
},
"startMs": {
"type": "integer",
"minimum": 0,
"maximum": 30000
},
"durationMs": {
"type": "integer",
"minimum": 100,
"maximum": 30000
},
"easing": {
"type": "string",
"enum": [
"linear",
"ease",
"ease-in",
"ease-out",
"ease-in-out"
]
}
},
"required": [
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false,
"description": "How the layer leaves the clip after its entrance has finished."
}
},
"required": [
"elementId",
"preset",
"startMs",
"durationMs",
"easing"
],
"additionalProperties": false
}
}
},
"required": [
"durationMs",
"fps",
"motions"
],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"canvas",
"elements",
"animation"
],
"additionalProperties": false
}
},
"exportSettings": {
"type": "object",
"properties": {
"format": {
"type": "string",
"enum": [
"svg",
"png",
"jpeg",
"mp4",
"pdf",
"pptx"
]
},
"scale": {
"type": "number",
"minimum": 0.25,
"maximum": 4
},
"quality": {
"type": "number",
"minimum": 0.1,
"maximum": 1
},
"transparent": {
"type": "boolean"
}
},
"required": [
"format",
"scale",
"quality",
"transparent"
],
"additionalProperties": false
}
},
"required": [
"schemaVersion",
"brand",
"fontSources",
"pages",
"exportSettings"
],
"additionalProperties": false,
"description": "The complete paged design document. All sections are required; schemaVersion is the literal 5. Sending a document replaces the stored document whole."
}
},
"required": [
"id",
"name",
"description",
"category",
"style",
"width",
"height",
"pageCount",
"updatedAt",
"document"
],
"additionalProperties": false
}
},
"required": [
"template"
],
"additionalProperties": false
},
"target": "api",
"destructive": false,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=library.publish",
"resource": {
"kind": "design_library_template",
"idPath": "$.template.id"
},
"effects": [
"Publishes one design into the starter library shared by every workspace, or replaces the one already published under this id.",
"Refused unless the calling organization owns the Design application."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission library:publish and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.library.list and confirm the template appears with the expected name and page count."
],
"examples": [
{
"input": {
"id": "starter-launch-post",
"name": "Launch post",
"summary": "A single-card launch announcement.",
"category": "Social",
"style": "Bold",
"rank": 0,
"document": {
"schemaVersion": 5,
"brand": null,
"fontSources": [],
"pages": [
{
"id": "page_1",
"name": "Cover",
"canvas": {
"width": 1080,
"height": 1350,
"background": "#0A2440"
},
"elements": [
{
"id": "title",
"name": "Display title",
"purpose": "Headline",
"type": "text",
"frame": {
"x": 92,
"y": 400,
"width": 896,
"height": 240,
"rotation": 0
},
"opacity": 1,
"hidden": false,
"locked": false,
"text": "A starter design",
"style": {
"fontFamily": "Helvetica Neue, Helvetica, Arial, sans-serif",
"fontSize": 96,
"minFontSize": 48,
"maxFontSize": 96,
"autoFit": true,
"fontWeight": 800,
"lineHeight": 1.05,
"letterSpacing": -2,
"color": "#FFFFFF",
"textAlign": "left",
"verticalAlign": "middle"
}
}
],
"animation": {
"durationMs": 3000,
"fps": 24,
"motions": []
}
}
],
"exportSettings": {
"format": "png",
"scale": 2,
"quality": 0.92,
"transparent": false
}
}
},
"expected": "A response matching the published outputSchema for library.publish."
}
],
"recovery": {
"mode": "compensating_action",
"actionId": "app_topolo_design.library.retire",
"instructions": "Invoke app_topolo_design.library.retire with the same id to take the template back out of the library."
},
"contractSource": "design-action-metadata",
"rollbackActionId": "app_topolo_design.library.retire",
"nextActionIds": [
"app_topolo_design.library.list"
]
},
"documentation": {
"example_input": {
"id": "starter-launch-post",
"name": "Launch post",
"summary": "A single-card launch announcement.",
"category": "Social",
"style": "Bold",
"rank": 0,
"document": {
"schemaVersion": 5,
"brand": null,
"fontSources": [],
"pages": [
{
"id": "page_1",
"name": "Cover",
"canvas": {
"width": 1080,
"height": 1350,
"background": "#0A2440"
},
"elements": [
{
"id": "title",
"name": "Display title",
"purpose": "Headline",
"type": "text",
"frame": {
"x": 92,
"y": 400,
"width": 896,
"height": 240,
"rotation": 0
},
"opacity": 1,
"hidden": false,
"locked": false,
"text": "A starter design",
"style": {
"fontFamily": "Helvetica Neue, Helvetica, Arial, sans-serif",
"fontSize": 96,
"minFontSize": 48,
"maxFontSize": 96,
"autoFit": true,
"fontWeight": 800,
"lineHeight": 1.05,
"letterSpacing": -2,
"color": "#FFFFFF",
"textAlign": "left",
"verticalAlign": "middle"
}
}
],
"animation": {
"durationMs": 3000,
"fps": 24,
"motions": []
}
}
],
"exportSettings": {
"format": "png",
"scale": 2,
"quality": 0.92,
"transparent": false
}
}
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "POST",
"path": "/api/templates",
"body": {
"id": "starter-launch-post",
"name": "Launch post",
"summary": "A single-card launch announcement.",
"category": "Social",
"style": "Bold",
"rank": 0,
"document": {
"schemaVersion": 5,
"brand": null,
"fontSources": [],
"pages": [
{
"id": "page_1",
"name": "Cover",
"canvas": {
"width": 1080,
"height": 1350,
"background": "#0A2440"
},
"elements": [
{
"id": "title",
"name": "Display title",
"purpose": "Headline",
"type": "text",
"frame": {
"x": 92,
"y": 400,
"width": 896,
"height": 240,
"rotation": 0
},
"opacity": 1,
"hidden": false,
"locked": false,
"text": "A starter design",
"style": {
"fontFamily": "Helvetica Neue, Helvetica, Arial, sans-serif",
"fontSize": 96,
"minFontSize": 48,
"maxFontSize": 96,
"autoFit": true,
"fontWeight": 800,
"lineHeight": 1.05,
"letterSpacing": -2,
"color": "#FFFFFF",
"textAlign": "left",
"verticalAlign": "middle"
}
}
],
"animation": {
"durationMs": 3000,
"fps": 24,
"motions": []
}
}
],
"exportSettings": {
"format": "png",
"scale": 2,
"quality": 0.92,
"transparent": false
}
}
}
},
"effects": "Publishes one design into the starter library shared by every workspace, or replaces the one already published under this id. Refused unless the calling organization owns the Design application.",
"verification": [
"Call app_topolo_design.library.list and confirm the template appears with the expected name and page count."
],
"recovery": [
{
"mode": "compensating_action",
"actionId": "app_topolo_design.library.retire",
"instructions": "Invoke app_topolo_design.library.retire with the same id to take the template back out of the library."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission library:publish and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=library.publish",
"resource": {
"kind": "design_library_template",
"idPath": "$.template.id"
},
"next_action_ids": [
"app_topolo_design.library.list"
],
"rollback_action_id": "app_topolo_design.library.retire"
},
"implementation": {
"status": "implemented",
"route_key": "POST /api/templates",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "library.retire",
"title": "Retire a library template",
"description": "Remove a template from the starter library without deleting the project behind it. Only the organization that owns Design may call this.",
"method": "DELETE",
"path": "/api/templates/:id",
"permission": "library:publish",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 160
}
},
"required": [
"id"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"retired": {
"type": "string"
}
},
"required": [
"retired"
],
"additionalProperties": false
},
"target": "api",
"destructive": true,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=library.retire",
"resource": {
"kind": "design_library_template",
"idPath": "$.retired"
},
"effects": [
"Removes one template from the starter library without deleting the project behind it.",
"Refused unless the calling organization owns the Design application."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission library:publish and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.library.list and confirm the template is no longer listed."
],
"examples": [
{
"input": {
"id": "starter-launch-post"
},
"expected": "A response matching the published outputSchema for library.retire."
}
],
"recovery": {
"mode": "irreversible",
"instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
},
"contractSource": "design-action-metadata",
"nextActionIds": [
"app_topolo_design.library.list"
]
},
"documentation": {
"example_input": {
"id": "starter-launch-post"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "DELETE",
"path": "/api/templates/:id",
"body": null
},
"effects": "Removes one template from the starter library without deleting the project behind it. Refused unless the calling organization owns the Design application.",
"verification": [
"Call app_topolo_design.library.list and confirm the template is no longer listed."
],
"recovery": [
{
"mode": "irreversible",
"instructions": "No safe automatic inverse is published. Confirm the change and retain any required export or snapshot before calling."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission library:publish and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=library.retire",
"resource": {
"kind": "design_library_template",
"idPath": "$.retired"
},
"next_action_ids": [
"app_topolo_design.library.list"
],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "DELETE /api/templates/*",
"evidence": "Matched to a served route extracted from canonical staging source."
}
},
{
"name": "privacy.erase",
"title": "Erase workspace data",
"description": "Permanently erase Design projects, uploaded media, generated exports, and settings for the selected workspace.",
"method": "DELETE",
"path": "/api/privacy/erase",
"permission": "privacy:write",
"readOnly": false,
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"confirmation": {
"type": "string",
"const": "ERASE"
}
},
"required": [
"confirmation"
],
"additionalProperties": false
},
"outputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"erased": {
"type": "boolean",
"const": true
},
"projects": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"exports": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"media": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"erased",
"projects",
"exports",
"media"
],
"additionalProperties": false
},
"target": "api",
"destructive": true,
"requiresConfirmation": true,
"agentAccess": "confirm",
"authorizationMode": "static",
"agentContract": {
"docsUrl": "https://docs.topolo.app/reference/actions?service=topolo-design&action=privacy.erase",
"resource": {
"kind": "workspace",
"idPath": "$.workspaceId"
},
"effects": [
"Permanently erases Design projects, export records, and generated R2 objects for the selected workspace."
],
"errors": [
{
"status": 401,
"code": "authentication_required",
"recovery": "Authenticate again or provide a valid Topolo API key."
},
{
"status": 403,
"code": "permission_denied",
"recovery": "Grant the credential permission privacy:write and the required workspace binding."
},
{
"status": 422,
"code": "invalid_input",
"recovery": "Correct the payload using inputSchema, then validate before retrying."
},
{
"status": 429,
"code": "rate_limited",
"recovery": "Wait for Retry-After when present, then retry without parallel duplicate calls."
},
{
"status": 503,
"code": "dependency_unavailable",
"recovery": "Retry the action. If it continues, inspect the structured error details using the request ID."
}
],
"verify": [
"Call app_topolo_design.privacy.export and confirm both projects and exports are empty."
],
"examples": [
{
"input": {
"confirmation": "ERASE"
},
"expected": "A response matching the published outputSchema for privacy.erase."
}
],
"recovery": {
"mode": "irreversible",
"instructions": "No rollback is available. Export the workspace first if its Design records must be retained."
},
"contractSource": "design-action-metadata"
},
"documentation": {
"example_input": {
"confirmation": "ERASE"
},
"cli_example": [
"topolo actions --service topolo-design --json",
"topolo actions get <action-id> --json",
"topolo actions validate <action-id> --data @payload.json --json",
"topolo actions plan <action-id> --data @payload.json --json",
"topolo actions call <action-id> --data @payload.json --confirm --json"
],
"http_example": {
"method": "DELETE",
"path": "/api/privacy/erase",
"body": null
},
"effects": "Permanently erases Design projects, export records, and generated R2 objects for the selected workspace.",
"verification": [
"Call app_topolo_design.privacy.export and confirm both projects and exports are empty."
],
"recovery": [
{
"mode": "irreversible",
"instructions": "No rollback is available. Export the workspace first if its Design records must be retained."
},
"401 authentication_required: Authenticate again or provide a valid Topolo API key.",
"403 permission_denied: Grant the credential permission privacy:write and the required workspace binding.",
"422 invalid_input: Correct the payload using inputSchema, then validate before retrying.",
"429 rate_limited: Wait for Retry-After when present, then retry without parallel duplicate calls.",
"503 dependency_unavailable: Retry the action. If it continues, inspect the structured error details using the request ID."
],
"docs_url": "https://docs.topolo.app/reference/actions?service=topolo-design&action=privacy.erase",
"resource": {
"kind": "workspace",
"idPath": "$.workspaceId"
},
"next_action_ids": [],
"rollback_action_id": null
},
"implementation": {
"status": "implemented",
"route_key": "DELETE /api/privacy/erase",
"evidence": "Matched to a served route extracted from canonical staging source."
}
}
],
"action_coverage": {
"status": "ok",
"served_routes": 44,
"matched_actions": 36,
"declared_unserved_actions": [
"DELETE /api/folders/*",
"PATCH /api/folders/*"
],
"coverage_excluded_actions": [],
"uncatalogued_routes": [
{
"key": "DELETE /api/folders",
"method": "DELETE",
"path": "/api/folders",
"source": "apps/api/src/design-routes.ts",
"target": "api"
},
{
"key": "PATCH /api/folders",
"method": "PATCH",
"path": "/api/folders",
"source": "apps/api/src/design-routes.ts",
"target": "api"
}
],
"ignored_routes": 6,
"configured_exclusions": 4,
"configuration_findings": [],
"notes": [
"14 manually-declared route(s)"
]
},
"runtime_contract_audit": {
"status": "verified",
"actions": 38,
"contracts": 38,
"contract_module": "topolo.action-contracts.mjs",
"validator_sources": [
"apps/api/src/worker.ts"
],
"authorization_sources": [
"apps/api/src/worker.ts"
],
"findings": []
}
}
],
"mobile_contracts": [],
"package_manifests": [],
"deployment_configs": [],
"source_signals": {
"api_routes": [
{
"method": "LITERAL",
"path": "/api/privacy/export",
"source_path": "apps/TopoloDesign/apps/api/src/design-routes.ts"
},
{
"method": "ALL",
"path": "*",
"source_path": "apps/TopoloDesign/apps/api/src/worker.ts"
},
{
"method": "LITERAL",
"path": "/api/health",
"source_path": "apps/TopoloDesign/apps/api/src/worker.ts"
},
{
"method": "LITERAL",
"path": "/api/app-identity",
"source_path": "apps/TopoloDesign/apps/api/src/worker.ts"
},
{
"method": "LITERAL",
"path": "/api/widget",
"source_path": "apps/TopoloDesign/apps/api/src/worker.ts"
},
{
"method": "LITERAL",
"path": "/api/bootstrap",
"source_path": "apps/TopoloDesign/apps/api/src/worker.ts"
}
],
"ui_routes": [
{
"path": "/getting-started",
"source_path": "apps/TopoloDesign/apps/web/src/App.tsx"
},
{
"path": "/app/templates",
"source_path": "apps/TopoloDesign/apps/web/src/app-routes.tsx"
},
{
"path": "/app/library",
"source_path": "apps/TopoloDesign/apps/web/src/app-routes.tsx"
},
{
"path": "/app/media",
"source_path": "apps/TopoloDesign/apps/web/src/app-routes.tsx"
},
{
"path": "/app/settings",
"source_path": "apps/TopoloDesign/apps/web/src/app-routes.tsx"
},
{
"path": "/app/settings/:section",
"source_path": "apps/TopoloDesign/apps/web/src/app-routes.tsx"
},
{
"path": "/app/projects/:projectId",
"source_path": "apps/TopoloDesign/apps/web/src/app-routes.tsx"
},
{
"path": "/getting-started",
"source_path": "apps/TopoloDesign/apps/web/src/app-routes.tsx"
},
{
"path": "/app/settings/workspace",
"source_path": "apps/TopoloDesign/apps/web/src/routes/SettingsRoute.tsx"
},
{
"path": "/app/settings/brand",
"source_path": "apps/TopoloDesign/apps/web/src/routes/SettingsRoute.tsx"
},
{
"path": "/app/settings/export",
"source_path": "apps/TopoloDesign/apps/web/src/routes/SettingsRoute.tsx"
},
{
"path": "/app/settings/api-keys",
"source_path": "apps/TopoloDesign/apps/web/src/routes/SettingsRoute.tsx"
}
],
"test_cases": [],
"database_tables": []
},
"documentation": {
"declared_paths": [
"applications/design",
"internal/apps/design"
],
"present_paths": [
"applications/design",
"internal/apps/design"
],
"missing_paths": [],
"human_reference": "/systems/topolo-design",
"machine_reference": "/machine/systems/topolo-design.json",
"action_examples": 38,
"action_schemas": 38
},
"source_findings": [
{
"type": "declared_unserved_actions",
"source_path": "apps/TopoloDesign/topolo.app.json",
"detail": [
"DELETE /api/folders/*",
"PATCH /api/folders/*"
]
},
{
"type": "uncatalogued_routes",
"source_path": "apps/TopoloDesign/topolo.app.json",
"detail": [
{
"key": "DELETE /api/folders",
"method": "DELETE",
"path": "/api/folders",
"source": "apps/api/src/design-routes.ts",
"target": "api"
},
{
"key": "PATCH /api/folders",
"method": "PATCH",
"path": "/api/folders",
"source": "apps/api/src/design-routes.ts",
"target": "api"
}
]
}
]
}