{"openapi":"3.1.0","info":{"title":"Kaitoi REST API","description":"Kaitoi's REST API exposes a stable integration surface for projects, editable\nproject documents, graph inspection, node discovery, files, runs, and future\nautomation workflows.\n\n**Authentication**\n\nSend a programmatic API key as `Authorization: Bearer <api_key>`. Keys can be\nscoped with endpoint-specific permissions such as `projects:read`,\n`projects:write`, `templates:read`, `templates:run`, `runs:execute`,\n`graphs:read`, `node_types:read`, `files:read`, and `files:write`.\nAccount credit balance reads require `account_credits:read`.\n\nKaitoi has two API key usage modes:\n\n- **Backend service keys** are the default for trusted code: your backend,\n  CLI tools, desktop apps, scripts, workers, and CI jobs. These keys are\n  bearer secrets and should not be shipped in browser JavaScript.\n- **Browser app keys** are for direct calls from frontend JavaScript. They\n  must be attached to a Developer App with explicit allowed origins. The\n  origin check lets browsers call the public REST API only from those\n  registered origins, but it is not a substitute for keeping sensitive secrets\n  on a trusted server. Browser keys are visible to end users, so prefer\n  read-only or narrowly scoped permissions.\n\nFor production web apps, the safest pattern is usually: browser frontend calls\nyour backend, and your backend calls Kaitoi with a Backend service key. Use\nBrowser app keys only when you intentionally want direct browser-to-Kaitoi\ncalls and have chosen scopes and quotas accordingly.\n\n**Base URL**\n\nAll REST API endpoints are served under `/api/v1`. The global FastAPI\ndocumentation endpoints remain disabled in production; this OpenAPI document is\nfiltered to REST API routes only.\n\n**API Artifacts**\n\nThe OpenAPI schema is available at `/api/v1/openapi.json`. A generated Postman\ncollection is available at `/api/v1/postman.json` and stays in sync with this\nschema as the REST API grows.\n\nLLM-friendly documentation is available at `/api/v1/llms.txt`, with a fuller\nMarkdown reference at `/api/v1/llms-full.txt`.\n\n**Rate Limits**\n\nRequests are rate limited per client IP before authentication and per API key\nafter authentication. `429 RATE_LIMITED` responses include a `Retry-After`\nheader and a JSON error body. Production/staging deployments enforce these\nlimits through the shared Redis-backed limiter so quotas apply across backend\ninstances. The default production behavior is fail-closed: if the shared\nlimiter is unavailable, requests return `503 RATE_LIMIT_UNAVAILABLE` with a\nshort `Retry-After` hint so clients back off instead of bypassing quotas.\nOperators can explicitly configure a per-instance local degradation mode for\nenvironments that prefer temporary availability over globally strict quotas.\nLocal development uses an in-process fallback unless Redis rate limiting is\nexplicitly enabled.\n\n**Errors**\n\nErrors use a consistent shape: `{ \"error\": { \"code\", \"message\", \"details\" } }`.\nWhen clients send `X-Request-Id`, the same identifier is echoed as\n`error.requestId` to simplify support and audit correlation.\n\n**Pagination**\n\nList endpoints use opaque keyset cursors. Treat `nextCursor` as an opaque token;\ndo not parse or construct it client-side.\n\n**Project Documents**\n\nUse `/projects/{projectId}/document` as the canonical editable project surface.\n`GET /projects/{projectId}/graph` is a read-oriented view and is not intended\nto be round-tripped back into document writes. Document writes require\n`expectedVersion` for optimistic concurrency and support idempotent retries.\n\n**Lifecycle Deletes**\n\nProject deletion is version-gated and archives the project from the public REST\nsurface. Completed file deletion is blocked while active projects reference the\nfile, and fails closed when a project's public file-reference index is unknown.","version":"1.0.0"},"paths":{"/api/v1/account/credits":{"get":{"tags":["Account"],"summary":"Get account credits","description":"Returns the authenticated user's current spendable account credit balance and PAYG/subscription breakdown. Requires the `account_credits:read` scope.","operationId":"account.getCredits","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Current account credit balance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicAccountCredits"}}}},"401":{"description":"Authentication is required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key is missing the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"Managed billing is not enabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects":{"post":{"tags":["Projects"],"summary":"Create project","description":"Creates an empty saved project for the authenticated API key owner. Use Idempotency-Key so retries do not create duplicate projects.","operationId":"projects.create","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectCreateRequest"}}}},"responses":{"201":{"description":"Created project metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The Idempotency-Key conflicts with a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Projects"],"summary":"List projects","description":"Returns projects visible to the authenticated API key owner. Results are ordered by most recently updated project first and paginated with opaque keyset cursors.","operationId":"projects.list","parameters":[{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of projects to return. Defaults to 50; capped at 200.","title":"Limit"},"description":"Maximum number of projects to return. Defaults to 50; capped at 200."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor returned from the previous page.","title":"Cursor"},"description":"Opaque cursor returned from the previous page."},{"name":"externalId","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by developer-provided external project identifier.","title":"Externalid"},"description":"Filter by developer-provided external project identifier."},{"name":"externalUserId","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by developer-provided end-user identifier.","title":"Externaluserid"},"description":"Filter by developer-provided end-user identifier."},{"name":"externalWorkspaceId","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by developer-provided workspace/team identifier.","title":"Externalworkspaceid"},"description":"Filter by developer-provided workspace/team identifier."},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Case-insensitive project-name search.","title":"Search"},"description":"Case-insensitive project-name search."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"A page of project summaries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicListResponse_PublicProjectSummary_"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}":{"get":{"tags":["Projects"],"summary":"Get project","description":"Returns public metadata for a single project, including the current project version used by future write endpoints for optimistic concurrency.","operationId":"projects.get","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Project metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Projects"],"summary":"Update project","description":"Updates project display metadata and developer-provided external identifiers using optimistic concurrency.","operationId":"projects.update","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectUpdateRequest"}}}},"responses":{"200":{"description":"Updated project metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The expected project version is stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Projects"],"summary":"Delete project","description":"Deletes a project from the public REST API surface using optimistic concurrency. The project bundle and metadata are removed from project storage so the project no longer appears in Studio or public REST project lists.","operationId":"projects.delete","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"expectedVersion","in":"query","required":true,"schema":{"type":"integer","minimum":0,"description":"Last project version observed by the client.","title":"Expectedversion"},"description":"Last project version observed by the client."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Project deleted."},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The expected project version is stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}/metadata":{"patch":{"tags":["Projects"],"summary":"Update project metadata","description":"Updates project display metadata and developer-provided external identifiers using optimistic concurrency. Prefer this explicit route for metadata-only updates; PATCH /projects/{project_id} is kept as a compatibility alias.","operationId":"projects.updateMetadata","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectUpdateRequest"}}}},"responses":{"200":{"description":"Updated project metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The expected project version is stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}/graph":{"get":{"tags":["Projects"],"summary":"Get project graph","description":"Returns a sanitized graph snapshot for a project. Internal metadata, execution history, and private storage paths are intentionally omitted.","operationId":"projects.getGraph","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"A sanitized project graph snapshot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicGraph"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}/graph/nodes/{node_id}":{"get":{"tags":["Projects"],"summary":"Get project graph node","description":"Returns one sanitized placed node from a project graph. Use fields=inputs,outputs for compact connection-pin discovery. Omit fields for the existing sanitized full graph-node shape.","operationId":"projects.getGraphNode","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"node_id","in":"path","required":true,"schema":{"type":"string","title":"Node Id"}},{"name":"fields","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional comma-separated pins projection: inputs, outputs. Omit for the full sanitized node response.","title":"Fields"},"description":"Optional comma-separated pins projection: inputs, outputs. Omit for the full sanitized node response."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"A sanitized placed graph node or compact pin projection.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/PublicGraphNode"},{"$ref":"#/components/schemas/PublicGraphNodeProjection"}],"title":"Response Projects.Getgraphnode"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project or graph node does not exist, or the project is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}/document":{"get":{"tags":["Projects"],"summary":"Get project document","description":"Returns the canonical editable project document. This shape is designed for developer round trips and uses input maps plus from/to connection tuples, unlike the read-only /graph inspection shape.","operationId":"projects.getDocument","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"An editable project document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectDocument"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Projects"],"summary":"Replace project document","description":"Replaces the editable project document using optimistic concurrency. The public document graph is validated, translated into Studio's internal bundle shape, and saved as a normal project. Use Idempotency-Key so network retries can replay the saved response.","operationId":"projects.replaceDocument","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectDocumentReplaceRequest"}}}},"responses":{"200":{"description":"The saved editable project document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectDocument"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The expected project version is stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Projects"],"summary":"Patch project document","description":"Applies ordered semantic document operations atomically using optimistic concurrency. The resulting document is validated and saved through the same path as PUT /document. Use Idempotency-Key so network retries can replay the saved response.","operationId":"projects.patchDocument","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectDocumentPatchRequest"}}}},"responses":{"200":{"description":"The saved editable project document plus patch metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectDocumentPatchResponse"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"A patch operation is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The expected project version is stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}/spend":{"get":{"tags":["Projects"],"summary":"Get project spend","description":"Returns actual billed credits from project-attributed ledger transactions. The response does not expose account balances, payment methods, or dollar amounts.","operationId":"projects.getSpend","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Project spend summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectSpendSummary"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/templates":{"get":{"tags":["Templates"],"summary":"List templates","description":"Returns user-owned templates visible to the authenticated API key owner. Use `hasEndpoint=true` to discover app-ready templates that already have at least one active endpoint. Use endpoint docs to inspect the external endpoint contract and the owner-authenticated Public API run path.","operationId":"templates.list","parameters":[{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of templates to return. Defaults to 50; capped at 200.","title":"Limit"},"description":"Maximum number of templates to return. Defaults to 50; capped at 200."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor returned from the previous page.","title":"Cursor"},"description":"Opaque cursor returned from the previous page."},{"name":"hasEndpoint","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter by whether a template has at least one active endpoint.","title":"Hasendpoint"},"description":"Filter by whether a template has at least one active endpoint."},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Case-insensitive search over template name, description, category, and tags.","title":"Search"},"description":"Case-insensitive search over template name, description, category, and tags."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"A page of template summaries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicListResponse_PublicTemplateSummary_"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/templates/{template_id}":{"get":{"tags":["Templates"],"summary":"Get template","description":"Returns public metadata for one user-owned template, including active endpoint summaries when the template has app-ready endpoints.","operationId":"templates.get","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Template metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTemplateDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The template does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/templates/{template_id}/endpoints":{"get":{"tags":["Templates"],"summary":"List template endpoints","description":"Returns active external endpoints for a user-owned template. Endpoint API secrets are never returned; use the endpoint docs response to learn the required Authorization header shape.","operationId":"templates.listEndpoints","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"A list of active endpoint summaries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicListResponse_PublicTemplateEndpointSummary_"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The template does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/templates/{template_id}/endpoints/{endpoint_id}/docs":{"get":{"tags":["Templates"],"summary":"Get template endpoint docs","description":"Returns docs for an active external endpoint on a user-owned template: authentication header shape, submit/status paths, and exposed input and output fields. This does not return endpoint API keys and does not run the endpoint.","operationId":"templates.getEndpointDocs","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}},{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","title":"Endpoint Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Endpoint documentation for app builders.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTemplateEndpointDocs"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The template endpoint does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/templates/{template_id}/endpoints/{endpoint_id}/runs":{"post":{"tags":["Templates"],"summary":"Run template endpoint","description":"Submits an owner-authenticated run for an active endpoint on a user-owned template. The API key user must own the template and endpoint, the key must have `templates:run`, file inputs must reference Public API fileIds, and execution may spend the owner's credits. Use `Idempotency-Key` so network retries do not submit duplicate jobs.","operationId":"templates.run","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}},{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","title":"Endpoint Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTemplateRunCreateRequest"}}}},"responses":{"202":{"description":"Accepted template endpoint run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTemplateRunDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The run inputs or file references are invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The template, endpoint, or input file was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The Idempotency-Key conflicts with a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/templates/{template_id}/endpoints/{endpoint_id}/runs/{task_id}":{"get":{"tags":["Templates"],"summary":"Get template endpoint run","description":"Returns a template endpoint run owned by the authenticated API key owner. Polling requires `templates:run` because completed results are part of the execution contract.","operationId":"templates.getRun","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}},{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","title":"Endpoint Id"}},{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Template endpoint run status and outputs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTemplateRunDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The template endpoint run was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/templates/{template_id}/endpoints/{endpoint_id}/runs/{task_id}/events/stream":{"get":{"tags":["Templates"],"summary":"Stream template endpoint run events","description":"Streams compact lifecycle and progress events for an owner-authenticated template endpoint run using Server-Sent Events. This endpoint requires `templates:run` because progress and completed results are part of the execution contract.","operationId":"templates.streamRunEvents","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","title":"Template Id"}},{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","title":"Endpoint Id"}},{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"A text/event-stream response containing compact template run events.","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The template endpoint run was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/files":{"post":{"tags":["Files"],"summary":"Upload small file","description":"Small-file convenience upload. This route is capped at 25 MB and is deprecated for developer-platform use; prefer POST /files/uploads.","operationId":"files.upload","deprecated":true,"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/upload"}}}},"responses":{"201":{"description":"Uploaded file metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicFileDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The uploaded file is empty or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The Idempotency-Key conflicts with a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"413":{"description":"The uploaded file exceeds the per-request size limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"507":{"description":"The upload would exceed the account storage limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/files/uploads":{"post":{"tags":["Files"],"summary":"Create file upload session","description":"Creates a direct-to-storage upload session. This endpoint does not upload the file bytes. Use the returned instructions as follows:\n\n1. Send a separate PUT request to `upload.url` using `upload.method` and every header in `upload.headers`. Do not send the API Bearer token to that URL; the signed URL is the temporary upload credential.\n2. After the PUT succeeds, call `POST /files/uploads/{upload_id}/complete` with this response's `uploadId`.\n3. Use the completed response's `fileId` as a file input in later API calls.\n\nFor large files, `storageMethod` may be `multipart`; in that case, PUT each item in `parts` and pass the returned ETags to the complete endpoint. If the session was created with `sha256`, the API verifies the stored object checksum before completion; multipart completions must include `actualSha256`. Use Idempotency-Key so retries return the same reservation and signed URL.","operationId":"files.createUpload","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicFileUploadCreateRequest"}}}},"responses":{"201":{"description":"Upload session and signed upload instructions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicFileUploadSession"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The upload session request is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The Idempotency-Key conflicts with a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"507":{"description":"The upload would exceed the account storage limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/files/uploads/{upload_id}/complete":{"post":{"tags":["Files"],"summary":"Complete file upload","description":"Verifies that the bytes were uploaded to the signed URL returned by `Create file upload session`, then promotes the object to a durable REST API file record. This call is idempotent by `upload_id`; retrying after a successful completion returns the same file metadata. When the session was created with `sha256`, the API verifies the stored object's SHA-256 before completing it.","operationId":"files.completeUpload","parameters":[{"name":"upload_id","in":"path","required":true,"schema":{"type":"string","title":"Upload Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicFileUploadCompleteRequest"}}}},"responses":{"200":{"description":"Completed file metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicFileDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The upload session does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"410":{"description":"The upload session expired or was aborted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"The uploaded object failed completion verification.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}}}}},"/api/v1/files/uploads/{upload_id}":{"delete":{"tags":["Files"],"summary":"Abort file upload","description":"Aborts a pending upload session and releases its storage reservation.","operationId":"files.abortUpload","parameters":[{"name":"upload_id","in":"path","required":true,"schema":{"type":"string","title":"Upload Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Upload session aborted or already absent."},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/files/{file_id}":{"get":{"tags":["Files"],"summary":"Get file","description":"Returns metadata for a REST API uploaded file owned by the authenticated account.","operationId":"files.get","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}},{"name":"externalUserId","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional developer-user guard. When provided, the file is returned only if its stored externalUserId matches this value.","title":"Externaluserid"},"description":"Optional developer-user guard. When provided, the file is returned only if its stored externalUserId matches this value."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"File metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicFileDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The file id is malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The file does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Files"],"summary":"Delete file","description":"Deletes a completed REST API file owned by the authenticated account. Deletion is blocked while active saved projects reference the file, and fails closed when any plausible active project has not indexed file references yet.","operationId":"files.delete","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}},{"name":"externalUserId","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional developer-user guard. When provided, the file is deleted only if its stored externalUserId matches this value.","title":"Externaluserid"},"description":"Optional developer-user guard. When provided, the file is deleted only if its stored externalUserId matches this value."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"File deleted."},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The file id is malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The file does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The file is still referenced by active projects, or reference safety cannot be proven yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"500":{"description":"The file could not be deleted from storage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/files/{file_id}/download-url":{"get":{"tags":["Files"],"summary":"Get file download URL","description":"Returns a short-lived signed URL for downloading a REST API uploaded file. The URL is time-limited and should not be stored permanently.","operationId":"files.getDownloadUrl","parameters":[{"name":"file_id","in":"path","required":true,"schema":{"type":"string","title":"File Id"}},{"name":"expiresInSeconds","in":"query","required":false,"schema":{"type":"integer","maximum":86400,"minimum":60,"description":"Signed URL lifetime in seconds. Defaults to 3600 and is capped at 86400.","default":3600,"title":"Expiresinseconds"},"description":"Signed URL lifetime in seconds. Defaults to 3600 and is capped at 86400."},{"name":"externalUserId","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional developer-user guard. When provided, a download URL is issued only if the file's stored externalUserId matches this value.","title":"Externaluserid"},"description":"Optional developer-user guard. When provided, a download URL is issued only if the file's stored externalUserId matches this value."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Signed download URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicFileDownloadUrl"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The file id is malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The file does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs":{"post":{"tags":["Runs"],"summary":"Create run","description":"Accepts a run request for either a saved project (`projectId`) or an inline transient graph (`graph`). The server validates file input references, target nodes, node types, and input pins; snapshots the selected graph source; creates an accepted run record; and dispatches execution asynchronously through the same run lifecycle.","operationId":"runs.create","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicRunCreateRequest"}}}},"responses":{"202":{"description":"Accepted run record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicRunDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The run could not be dispatched or the shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The run request or input references are invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The project or an input file was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The Idempotency-Key conflicts with a different request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}":{"get":{"tags":["Runs"],"summary":"Get run","description":"Returns a REST API run record owned by the authenticated API key owner.","operationId":"runs.get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Run record.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicRunDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The run does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}/apply-to-project":{"post":{"tags":["Runs"],"summary":"Apply run outputs to project","description":"Persists outputs from a succeeded saved-project run back into that saved project. This is the public API equivalent of saving the server-owned run result state after execution; it does not accept client-supplied output values. The request uses optimistic concurrency and fails if the project changed after the run was created.","operationId":"runs.applyOutputsToProject","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicRunApplyOutputsRequest"}}}},"responses":{"200":{"description":"Project version and output keys that were applied.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicRunApplyOutputsResponse"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The output selection is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The run, project, or run output file was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The run is not applicable or the project version is stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}/cancel":{"post":{"tags":["Runs"],"summary":"Cancel run","description":"Requests cancellation for a REST API run. Accepted or queued runs become terminal canceled immediately; running runs are marked cancelRequested for the execution layer to stop at the next safe point.","operationId":"runs.cancel","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Run record after the cancellation request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicRunDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The run does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The run is already terminal and cannot be canceled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}/events":{"get":{"tags":["Runs"],"summary":"List run events","description":"Returns persisted lifecycle, progress, and log events for a REST API run. Cursors are opaque and are only valid for the same run and API key owner that issued them.","operationId":"runs.listEvents","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of events to return. Defaults to 50; capped at 200.","title":"Limit"},"description":"Maximum number of events to return. Defaults to 50; capped at 200."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor returned from the previous page.","title":"Cursor"},"description":"Opaque cursor returned from the previous page."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"A page of run events.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicListResponse_PublicRunEvent_"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The cursor or limit is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The run does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/runs/{run_id}/events/stream":{"get":{"tags":["Runs"],"summary":"Stream run events","description":"Streams the same persisted lifecycle, progress, and log events returned by the polling endpoint using Server-Sent Events. The SSE id is an opaque cursor and can be sent back as Last-Event-ID or as the cursor query parameter to resume the stream.","operationId":"runs.streamEvents","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor returned by a previous poll page or SSE id.","title":"Cursor"},"description":"Opaque cursor returned by a previous poll page or SSE id."},{"name":"Last-Event-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last-Event-Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"A text/event-stream response containing PublicRunEvent payloads.","content":{"application/json":{"schema":{}},"text/event-stream":{}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The cursor is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The run does not exist or is not owned by this user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/node-types":{"get":{"tags":["Node Types"],"summary":"List node types","description":"Returns node types available to the authenticated user. Use this endpoint to discover compatible node identifiers before building automation against a graph.","operationId":"nodeTypes.list","parameters":[{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum number of node types to return. Defaults to 50; capped at 200.","title":"Limit"},"description":"Maximum number of node types to return. Defaults to 50; capped at 200."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor returned from the previous page.","title":"Cursor"},"description":"Opaque cursor returned from the previous page."},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Smart search over node type, title, category, description, and tags using the shared node catalog ranking.","title":"Search"},"description":"Smart search over node type, title, category, description, and tags using the shared node catalog ranking."},{"name":"fields","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional comma-separated response projection. `type` is always returned. Omit for the existing full summary response.","title":"Fields"},"description":"Optional comma-separated response projection. `type` is always returned. Omit for the existing full summary response."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"A page of node type summaries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicListResponse_PublicNodeTypeSummary_"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/node-type-thumbnails/{node_type}":{"get":{"tags":["Node Types"],"summary":"Get node type thumbnail","description":"Serves a short-lived signed node type thumbnail URL returned by the node type list and detail endpoints. The token in the URL authorizes only this thumbnail; do not send the REST API bearer token to this URL.","operationId":"nodeTypes.getThumbnail","parameters":[{"name":"node_type","in":"path","required":true,"schema":{"type":"string","title":"Node Type"}},{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"Signed thumbnail token returned by nodeTypes.list or nodeTypes.get.","title":"Token"},"description":"Signed thumbnail token returned by nodeTypes.list or nodeTypes.get."},{"name":"index","in":"query","required":false,"schema":{"type":"integer","maximum":2,"minimum":1,"description":"Thumbnail index. 1 is primary; 2 is secondary when available.","default":1,"title":"Index"},"description":"Thumbnail index. 1 is primary; 2 is secondary when available."}],"responses":{"200":{"description":"Node type thumbnail image.","content":{"application/json":{"schema":{}}}},"400":{"description":"The node type path or thumbnail source is malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The signed thumbnail URL is invalid or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The node type or thumbnail was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/node-types/{node_type}":{"get":{"tags":["Node Types"],"summary":"Get node type","description":"Returns the public schema for one node type, including its exposed input and output pins. Node type paths are validated before lookup so user-node paths cannot traverse storage boundaries.","operationId":"nodeTypes.get","parameters":[{"name":"node_type","in":"path","required":true,"schema":{"type":"string","title":"Node Type"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Detailed node type metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicNodeTypeDetail"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The node type path is malformed or unsafe.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"The node type was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/storyboards/schema/kaitoi-storyboard-document.v1":{"get":{"tags":["Storyboards"],"summary":"Get storyboard document schema","description":"Returns the canonical Kaitoi Storyboard Document v1 JSON Schema. This route is unauthenticated so public API clients can validate documents before sending them.","operationId":"storyboards.getSchema","responses":{"200":{"description":"Kaitoi Storyboard Document v1 JSON Schema.","content":{"application/json":{"schema":{}}}}}}},"/api/v1/storyboards/validate":{"post":{"tags":["Storyboards"],"summary":"Validate storyboard document","description":"Validates a Kaitoi Storyboard Document v1 against the same schema enforced by the backend.","operationId":"storyboards.validate","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicStoryboardValidateRequest"}}}},"responses":{"200":{"description":"Validated storyboard document and derived summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicStoryboardValidationResponse"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The storyboard document is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/storyboards/to-timeline":{"post":{"tags":["Storyboards"],"summary":"Convert storyboard document to timeline document","description":"Converts a Kaitoi Storyboard Document v1 into a Kaitoi Timeline Document v1 without mutating any project. Storyboard shots become sequential timeline clips; URL, document, unresolved, and unsupported media references are skipped with warnings instead of being fetched.","operationId":"storyboards.toTimeline","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicStoryboardToTimelineRequest"}}}},"responses":{"200":{"description":"Generated timeline document and non-fatal conversion warnings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicStoryboardToTimelineResponse"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The storyboard document is invalid or cannot be converted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}/storyboard":{"get":{"tags":["Storyboards"],"summary":"Get project storyboard","description":"Returns the project's current storyboard as a Kaitoi Storyboard Document v1. This is a read-only export of storyboard state.","operationId":"projects.getStoryboard","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Project storyboard document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectStoryboard"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"Project not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Storyboards"],"summary":"Update project storyboard","description":"Applies a Kaitoi Storyboard Document v1 to a saved project using optimistic concurrency. Supports replacing the current storyboard or appending imported scenes. Use Idempotency-Key so network retries can replay the saved response.","operationId":"projects.updateStoryboard","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectStoryboardReplaceRequest"}}}},"responses":{"200":{"description":"Saved project storyboard document and apply summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectStoryboardApplyResponse"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The storyboard document is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"Project not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The expected project version is stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/timelines/schema/kaitoi-timeline-document.v1":{"get":{"tags":["Timelines"],"summary":"Get timeline document schema","description":"Returns the canonical Kaitoi Timeline Document v1 JSON Schema. This route is unauthenticated so public API clients can validate documents before sending them.","operationId":"timelines.getSchema","responses":{"200":{"description":"Kaitoi Timeline Document v1 JSON Schema.","content":{"application/json":{"schema":{}}}}}}},"/api/v1/timelines/validate":{"post":{"tags":["Timelines"],"summary":"Validate timeline document","description":"Validates a Kaitoi Timeline Document v1 against the same schema enforced by the backend.","operationId":"timelines.validate","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTimelineValidateRequest"}}}},"responses":{"200":{"description":"Validated timeline document and derived summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTimelineValidationResponse"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The timeline document is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/timelines/export/otio":{"post":{"tags":["Timelines"],"summary":"Export timeline document as OTIO","description":"Converts a Kaitoi Timeline Document v1 to an OpenTimelineIO ZIP bundle. The ZIP contains `timeline.otio` and any media files the API can resolve from the authenticated account. OTIO media references are portable filenames, never server paths, storage roots, private bucket keys, or signed URLs.","operationId":"timelines.exportOtio","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTimelineOtioExportRequest"}}}},"responses":{"200":{"description":"OTIO ZIP bundle.","content":{"application/json":{"schema":{}},"application/zip":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The timeline document is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"501":{"description":"OpenTimelineIO is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/timelines/import/otio/parse":{"post":{"tags":["Timelines"],"summary":"Parse OTIO to timeline document","description":"Parses an `.otio` file or ZIP bundle into a Kaitoi Timeline Document v1 without persisting uploaded media. Returned media references are portable filenames and warnings explain that media was not stored.","operationId":"timelines.parseOtio","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/parseOtio"}}}},"responses":{"200":{"description":"Timeline document converted from OTIO.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTimelineOtioImportResponse"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The OTIO upload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"413":{"description":"The upload exceeds the request size limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"501":{"description":"OpenTimelineIO is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/timelines/import/otio":{"post":{"tags":["Timelines"],"summary":"Import OTIO to timeline document","description":"Imports an `.otio` file or ZIP bundle into a Kaitoi Timeline Document v1. When media files are present in the ZIP, they are persisted to the authenticated account's library and the returned document references those library filenames. Missing media produces warnings instead of server path leaks.","operationId":"timelines.importOtio","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/importOtio"}}}},"responses":{"200":{"description":"Timeline document converted from OTIO, with persisted media info.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTimelineOtioImportResponse"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The OTIO upload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"413":{"description":"The upload exceeds the request size limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"501":{"description":"OpenTimelineIO is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}/timeline":{"get":{"tags":["Timelines"],"summary":"Get project timeline","description":"Returns the project's current active timeline as a Kaitoi Timeline Document v1. This is a read-only export of timeline state.","operationId":"projects.getTimeline","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Project timeline document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectTimeline"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"Project not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Timelines"],"summary":"Update project timeline","description":"Replaces a saved project's active timeline with a Kaitoi Timeline Document v1 using optimistic concurrency. Use Idempotency-Key so network retries can replay the saved response. This replaces the whole project timeline; if the project currently has multiple timeline scenes, they are collapsed to the single timeline contained in the document.","operationId":"projects.updateTimeline","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectTimelineReplaceRequest"}}}},"responses":{"200":{"description":"Saved project timeline document and summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicProjectTimelineApplyResponse"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"400":{"description":"The timeline document is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"Project not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"409":{"description":"The expected project version is stale.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{project_id}/timeline/export/otio":{"get":{"tags":["Timelines"],"summary":"Export project timeline as OTIO","description":"Exports a saved project's current active timeline as an OpenTimelineIO ZIP bundle. Media references in the OTIO file are portable filenames, not server paths, storage roots, private bucket keys, or signed URLs.","operationId":"projects.exportTimelineOtio","parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"OTIO ZIP bundle.","content":{"application/json":{"schema":{}},"application/zip":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Missing, malformed, expired, or revoked bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"The API key lacks the required scope or account capability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"description":"The client or API key exceeded the REST API rate limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"503":{"description":"The shared REST API rate limiter is temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"404":{"description":"Project not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"501":{"description":"OpenTimelineIO is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"PublicAccountCredits":{"properties":{"balanceCents":{"type":"integer","title":"Balancecents","description":"Total spendable account balance in credits/cents.","examples":[1250]},"balanceMicrocredits":{"type":"string","title":"Balancemicrocredits","description":"Exact spendable balance in millionths of one credit.","examples":["1250110000"]},"ledgerUnitVersion":{"type":"integer","title":"Ledgerunitversion","description":"Authoritative account-ledger unit version."},"balanceDollars":{"type":"number","title":"Balancedollars","description":"Total spendable balance in USD dollars.","examples":[12.5]},"paygBalanceCents":{"type":"integer","title":"Paygbalancecents","description":"Purchased pay-as-you-go balance in credits/cents.","examples":[750]},"paygBalanceMicrocredits":{"type":"string","title":"Paygbalancemicrocredits"},"paygBalanceDollars":{"type":"number","title":"Paygbalancedollars","description":"Purchased pay-as-you-go balance in USD dollars.","examples":[7.5]},"subscriptionBalanceCents":{"type":"integer","title":"Subscriptionbalancecents","description":"Included subscription balance in credits/cents.","examples":[500]},"subscriptionBalanceMicrocredits":{"type":"string","title":"Subscriptionbalancemicrocredits"},"subscriptionBalanceDollars":{"type":"number","title":"Subscriptionbalancedollars","description":"Included subscription balance in USD dollars.","examples":[5.0]},"subscriptionMonthlyGrantCents":{"type":"integer","title":"Subscriptionmonthlygrantcents","description":"Monthly subscription credit grant in credits/cents.","examples":[1000]},"subscriptionMonthlyGrantMicrocredits":{"type":"string","title":"Subscriptionmonthlygrantmicrocredits"},"subscriptionRolloverCapCents":{"type":"integer","title":"Subscriptionrollovercapcents","description":"Maximum subscription rollover balance in credits/cents.","examples":[2000]},"subscriptionRolloverCapMicrocredits":{"type":"string","title":"Subscriptionrollovercapmicrocredits"},"managedProviderReceivableMicrocredits":{"type":"string","title":"Managedproviderreceivablemicrocredits","description":"Outstanding provider cost that must be repaid before new managed work."},"subscriptionPlanTier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscriptionplantier","description":"Current subscription plan tier, when available."},"subscriptionPeriodEnd":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Subscriptionperiodend","description":"Current subscription period end, when available."},"updatedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updatedat","description":"Timestamp when the balance record was last updated."}},"type":"object","required":["balanceCents","balanceMicrocredits","ledgerUnitVersion","balanceDollars","paygBalanceCents","paygBalanceMicrocredits","paygBalanceDollars","subscriptionBalanceCents","subscriptionBalanceMicrocredits","subscriptionBalanceDollars","subscriptionMonthlyGrantCents","subscriptionMonthlyGrantMicrocredits","subscriptionRolloverCapCents","subscriptionRolloverCapMicrocredits","managedProviderReceivableMicrocredits"],"title":"PublicAccountCredits","example":{"balanceCents":1250,"balanceDollars":12.5,"balanceMicrocredits":"1250110000","ledgerUnitVersion":2,"managedProviderReceivableMicrocredits":"0","paygBalanceCents":750,"paygBalanceDollars":7.5,"paygBalanceMicrocredits":"750110000","subscriptionBalanceCents":500,"subscriptionBalanceDollars":5.0,"subscriptionBalanceMicrocredits":"500000000","subscriptionMonthlyGrantCents":1000,"subscriptionMonthlyGrantMicrocredits":"1000000000","subscriptionPeriodEnd":"2026-06-30T00:00:00Z","subscriptionPlanTier":"pro","subscriptionRolloverCapCents":2000,"subscriptionRolloverCapMicrocredits":"2000000000","updatedAt":"2026-06-09T12:00:00Z"}},"PublicApiErrorBody":{"properties":{"code":{"type":"string","title":"Code","description":"Stable machine-readable error code.","examples":["PROJECT_NOT_FOUND"]},"message":{"type":"string","title":"Message","description":"Human-readable error summary.","examples":["Project not found."]},"details":{"additionalProperties":true,"type":"object","title":"Details","description":"Additional structured error details.","examples":[{"projectId":"proj_123"}]},"requestId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requestid","description":"Request identifier echoed from X-Request-Id when provided.","examples":["req_123"]}},"type":"object","required":["code","message"],"title":"PublicApiErrorBody","example":{"code":"PROJECT_NOT_FOUND","details":{"projectId":"proj_123"},"message":"Project not found.","requestId":"req_123"}},"PublicApiErrorResponse":{"properties":{"error":{"$ref":"#/components/schemas/PublicApiErrorBody","description":"REST API error payload."}},"type":"object","required":["error"],"title":"PublicApiErrorResponse","example":{"error":{"code":"PROJECT_NOT_FOUND","details":{"projectId":"proj_123"},"message":"Project not found."}}},"PublicConnection":{"properties":{"sourceNodeId":{"type":"string","title":"Sourcenodeid","description":"Source node identifier.","examples":["node_123"]},"sourcePin":{"type":"string","title":"Sourcepin","description":"Source output pin name.","examples":["text"]},"targetNodeId":{"type":"string","title":"Targetnodeid","description":"Target node identifier.","examples":["node_456"]},"targetPin":{"type":"string","title":"Targetpin","description":"Target input pin name.","examples":["prompt"]}},"type":"object","required":["sourceNodeId","sourcePin","targetNodeId","targetPin"],"title":"PublicConnection","example":{"sourceNodeId":"node_123","sourcePin":"text","targetNodeId":"node_456","targetPin":"prompt"}},"PublicEditableConnection":{"properties":{"from":{"prefixItems":[{"type":"string"},{"type":"string"}],"type":"array","maxItems":2,"minItems":2,"title":"From","description":"Source node id and output pin name.","examples":[["node_123","text"]]},"to":{"prefixItems":[{"type":"string"},{"type":"string"}],"type":"array","maxItems":2,"minItems":2,"title":"To","description":"Target node id and input pin name.","examples":[["node_456","prompt"]]}},"additionalProperties":true,"type":"object","required":["from","to"],"title":"PublicEditableConnection","example":{"from":["node_123","text"],"to":["node_456","prompt"]}},"PublicEditableGraph-Input":{"properties":{"nodes":{"items":{"$ref":"#/components/schemas/PublicEditableNode"},"type":"array","title":"Nodes","description":"Editable project nodes."},"connections":{"items":{"$ref":"#/components/schemas/PublicEditableConnection"},"type":"array","title":"Connections","description":"Editable project connections using from/to tuples."}},"additionalProperties":true,"type":"object","title":"PublicEditableGraph","example":{"connections":[{"from":["node_123","text"],"to":["node_456","prompt"]}],"nodes":[{"id":"node_123","inputs":{"inputPrompt":{"type":"string","value":"A cinematic wide shot"}},"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"}]}},"PublicEditableGraph-Output":{"properties":{"nodes":{"items":{"$ref":"#/components/schemas/PublicEditableNode"},"type":"array","title":"Nodes","description":"Editable project nodes."},"connections":{"items":{"$ref":"#/components/schemas/PublicEditableConnection"},"type":"array","title":"Connections","description":"Editable project connections using from/to tuples."}},"additionalProperties":true,"type":"object","title":"PublicEditableGraph","example":{"connections":[{"from":["node_123","text"],"to":["node_456","prompt"]}],"nodes":[{"id":"node_123","inputs":{"inputPrompt":{"type":"string","value":"A cinematic wide shot"}},"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"}]}},"PublicEditableInputValue":{"properties":{"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type","description":"Public data type for the input pin.","examples":["string"]},"value":{"anyOf":[{},{"type":"null"}],"title":"Value","description":"Current editable value for the input pin."}},"additionalProperties":true,"type":"object","title":"PublicEditableInputValue","example":{"type":"string","value":"A cinematic wide shot"}},"PublicEditableNode":{"properties":{"id":{"type":"string","title":"Id","description":"Stable node instance identifier.","examples":["node_123"]},"type":{"type":"string","title":"Type","description":"Node type identifier.","examples":["builtin/utils/text_prompt"]},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Node display title.","examples":["Text Prompt"]},"inputs":{"additionalProperties":{"$ref":"#/components/schemas/PublicEditableInputValue"},"type":"object","title":"Inputs","description":"Editable input values keyed by input pin name."},"position":{"anyOf":[{"$ref":"#/components/schemas/PublicEditablePosition"},{"type":"null"}],"description":"Canvas position for the node."}},"additionalProperties":true,"type":"object","required":["id","type"],"title":"PublicEditableNode","example":{"id":"node_123","inputs":{"inputPrompt":{"type":"string","value":"A cinematic wide shot"}},"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"}},"PublicEditablePosition":{"properties":{"x":{"type":"number","title":"X","description":"Node X position on the graph canvas.","examples":[120.0]},"y":{"type":"number","title":"Y","description":"Node Y position on the graph canvas.","examples":[240.0]}},"additionalProperties":true,"type":"object","required":["x","y"],"title":"PublicEditablePosition","example":{"x":120.0,"y":240.0}},"PublicFileDetail":{"properties":{"fileId":{"type":"string","title":"Fileid","description":"Stable file identifier for REST API inputs and outputs."},"filename":{"type":"string","title":"Filename","description":"Original filename supplied by the developer."},"contentType":{"type":"string","title":"Contenttype","description":"Detected or supplied media type."},"sizeBytes":{"type":"integer","minimum":0.0,"title":"Sizebytes","description":"Stored file size in bytes."},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalid","description":"Developer-provided external file identifier."},"externalUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externaluserid","description":"Developer-provided end-user identifier."},"externalWorkspaceId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalworkspaceid","description":"Developer-provided workspace/team identifier."},"createdAt":{"type":"string","format":"date-time","title":"Createdat","description":"Upload timestamp."},"updatedAt":{"type":"string","format":"date-time","title":"Updatedat","description":"Last metadata update timestamp."}},"type":"object","required":["fileId","filename","contentType","sizeBytes","createdAt","updatedAt"],"title":"PublicFileDetail","example":{"contentType":"image/png","createdAt":"2026-05-24T12:00:00+00:00","externalId":"asset_123","externalUserId":"user_789","externalWorkspaceId":"team_456","fileId":"2f8f8c5df80e4f76a5b7d1bbd6fae0ab.png","filename":"input.png","sizeBytes":12345,"updatedAt":"2026-05-24T12:00:00+00:00"}},"PublicFileDownloadUrl":{"properties":{"fileId":{"type":"string","title":"Fileid","description":"Stable file identifier."},"downloadUrl":{"type":"string","title":"Downloadurl","description":"Short-lived signed URL for downloading the file."},"expiresAt":{"type":"string","format":"date-time","title":"Expiresat","description":"Signed URL expiration timestamp."}},"type":"object","required":["fileId","downloadUrl","expiresAt"],"title":"PublicFileDownloadUrl","example":{"downloadUrl":"https://example.com/data/2f8f8c5d.png?token=...","expiresAt":"2026-05-24T13:00:00+00:00","fileId":"2f8f8c5df80e4f76a5b7d1bbd6fae0ab.png"}},"PublicFileOutput":{"properties":{"type":{"type":"string","const":"file","title":"Type","default":"file"},"fileId":{"type":"string","title":"Fileid"},"filename":{"type":"string","title":"Filename"},"contentType":{"type":"string","title":"Contenttype"},"sizeBytes":{"type":"integer","minimum":0.0,"title":"Sizebytes"},"downloadUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Downloadurl"},"expiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expiresat"},"previewUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previewurl"},"previewExpiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Previewexpiresat"}},"type":"object","required":["fileId","filename","contentType","sizeBytes"],"title":"PublicFileOutput"},"PublicFileUploadCompleteRequest":{"properties":{"actualSizeBytes":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Actualsizebytes","description":"Optional client-observed byte count."},"actualSha256":{"anyOf":[{"type":"string","pattern":"^[a-f0-9]{64}$"},{"type":"null"}],"title":"Actualsha256","description":"Optional client-observed lowercase hex SHA-256. Required for multipart uploads when the session was created with sha256."},"multipartParts":{"anyOf":[{"items":{"$ref":"#/components/schemas/PublicMultipartUploadPart"},"type":"array"},{"type":"null"}],"title":"Multipartparts","description":"Required for multipart uploads. Use the ETag returned by each part PUT response."}},"type":"object","title":"PublicFileUploadCompleteRequest","example":{"actualSha256":"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08","actualSizeBytes":12345}},"PublicFileUploadCreateRequest":{"properties":{"filename":{"type":"string","maxLength":255,"minLength":1,"title":"Filename","description":"Original filename."},"contentType":{"type":"string","maxLength":255,"minLength":1,"title":"Contenttype","description":"Media type to attach to the uploaded object.","default":"application/octet-stream"},"sizeBytes":{"type":"integer","exclusiveMinimum":0.0,"title":"Sizebytes","description":"Exact file size in bytes. This reserves storage quota before bytes are uploaded."},"sha256":{"anyOf":[{"type":"string","pattern":"^[a-f0-9]{64}$"},{"type":"null"}],"title":"Sha256","description":"Optional lowercase hex SHA-256. Recommended so the API can verify end-to-end object integrity before completing the upload."},"externalId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalid","description":"Developer-provided external file identifier."},"externalUserId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externaluserid","description":"Developer-provided end-user identifier."},"externalWorkspaceId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalworkspaceid","description":"Developer-provided workspace/team identifier."}},"type":"object","required":["filename","sizeBytes"],"title":"PublicFileUploadCreateRequest","example":{"contentType":"image/png","externalId":"asset_123","externalUserId":"user_789","externalWorkspaceId":"team_456","filename":"input.png","sha256":"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08","sizeBytes":12345}},"PublicFileUploadInstruction":{"properties":{"method":{"type":"string","const":"PUT","title":"Method","description":"HTTP method to use when uploading bytes to this signed URL."},"url":{"type":"string","title":"Url","description":"Signed upload URL for the file bytes. Send a separate PUT request to this URL without the API Bearer token; the URL itself is the temporary upload credential."},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers","description":"Headers that must be sent with the PUT request, such as Content-Type or storage checksum headers."}},"type":"object","required":["method","url"],"title":"PublicFileUploadInstruction"},"PublicFileUploadPartInstruction":{"properties":{"partNumber":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Partnumber","description":"Multipart part number."},"method":{"type":"string","const":"PUT","title":"Method","description":"HTTP method to use when uploading this part."},"url":{"type":"string","title":"Url","description":"Signed URL for this multipart part. Send this request without the API Bearer token."},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers","description":"Headers that must be sent with this part upload."}},"type":"object","required":["partNumber","method","url"],"title":"PublicFileUploadPartInstruction"},"PublicFileUploadSession":{"properties":{"uploadId":{"type":"string","title":"Uploadid","description":"Upload session id. Use this with POST /files/uploads/{uploadId}/complete."},"fileId":{"type":"string","title":"Fileid","description":"File id reserved for this upload. It becomes readable after completion."},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalid","description":"Developer-provided external file identifier."},"externalUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externaluserid","description":"Developer-provided end-user identifier."},"externalWorkspaceId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalworkspaceid","description":"Developer-provided workspace/team identifier."},"storageMethod":{"type":"string","enum":["single_part","multipart","proxied_relay"],"title":"Storagemethod","description":"Upload strategy selected by the API. For single_part and proxied_relay, send one PUT to upload.url. For multipart, send each PUT in parts, then include the returned ETags when completing the upload."},"expiresAt":{"type":"string","format":"date-time","title":"Expiresat","description":"Upload session expiration timestamp."},"upload":{"anyOf":[{"$ref":"#/components/schemas/PublicFileUploadInstruction"},{"type":"null"}],"description":"Single PUT upload instructions. Present for single_part and proxied_relay sessions."},"partSizeBytes":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Partsizebytes","description":"Target multipart part size in bytes."},"partCount":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Partcount","description":"Number of multipart parts to upload."},"parts":{"anyOf":[{"items":{"$ref":"#/components/schemas/PublicFileUploadPartInstruction"},"type":"array"},{"type":"null"}],"title":"Parts","description":"Multipart upload instructions. Present when storageMethod is multipart."}},"type":"object","required":["uploadId","fileId","storageMethod","expiresAt"],"title":"PublicFileUploadSession","example":{"expiresAt":"2026-05-24T13:00:00+00:00","externalId":"asset_123","externalUserId":"user_789","externalWorkspaceId":"team_456","fileId":"2f8f8c5df80e4f76a5b7d1bbd6fae0ab.png","storageMethod":"single_part","upload":{"headers":{"Content-Type":"image/png"},"method":"PUT","url":"https://storage.example.com/signed-upload-url"},"uploadId":"upl_8d7f7f7e1dd64d3e8e2d0d2e4b3c9a1f"}},"PublicGraph":{"properties":{"projectId":{"type":"string","title":"Projectid","description":"Project identifier for this graph snapshot.","examples":["proj_123"]},"version":{"type":"integer","title":"Version","description":"Project version used to build this graph snapshot.","examples":[7]},"nodes":{"items":{"$ref":"#/components/schemas/PublicGraphNode"},"type":"array","title":"Nodes","description":"Nodes in the public graph snapshot."},"connections":{"items":{"$ref":"#/components/schemas/PublicConnection"},"type":"array","title":"Connections","description":"Connections between graph pins."}},"type":"object","required":["projectId","version","nodes","connections"],"title":"PublicGraph","example":{"connections":[],"nodes":[{"id":"node_123","inputs":[],"outputs":[{"exposed":false,"name":"outputPrompt","type":"string"}],"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"}],"projectId":"proj_123","version":7}},"PublicGraphNode":{"properties":{"id":{"type":"string","title":"Id","description":"Stable node instance identifier.","examples":["node_123"]},"type":{"type":"string","title":"Type","description":"Node type identifier.","examples":["builtin/utils/text_prompt"]},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Node display title.","examples":["Text Prompt"]},"position":{"anyOf":[{"$ref":"#/components/schemas/PublicPosition"},{"type":"null"}],"description":"Canvas position for the node."},"inputs":{"items":{"$ref":"#/components/schemas/PublicNodePin"},"type":"array","title":"Inputs","description":"Publicly visible node inputs."},"outputs":{"items":{"$ref":"#/components/schemas/PublicNodePin"},"type":"array","title":"Outputs","description":"Publicly visible node outputs."}},"type":"object","required":["id","type","inputs","outputs"],"title":"PublicGraphNode","example":{"id":"node_123","inputs":[{"exposed":true,"label":"Prompt","name":"inputPrompt","type":"string","value":"A cinematic wide shot"}],"outputs":[{"exposed":false,"name":"outputPrompt","type":"string"}],"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"}},"PublicGraphNodeProjection":{"properties":{"inputs":{"anyOf":[{"items":{"$ref":"#/components/schemas/PublicProjectedNodePin"},"type":"array"},{"type":"null"}],"title":"Inputs","description":"Compact input pins when requested through fields."},"outputs":{"anyOf":[{"items":{"$ref":"#/components/schemas/PublicProjectedNodePin"},"type":"array"},{"type":"null"}],"title":"Outputs","description":"Compact output pins when requested through fields."}},"type":"object","title":"PublicGraphNodeProjection"},"PublicInlineGraph":{"properties":{"nodes":{"items":{"$ref":"#/components/schemas/PublicInlineGraphNode"},"type":"array","title":"Nodes"},"connections":{"items":{"$ref":"#/components/schemas/PublicInlineGraphConnection"},"type":"array","title":"Connections"}},"additionalProperties":true,"type":"object","required":["nodes"],"title":"PublicInlineGraph"},"PublicInlineGraphConnection":{"properties":{"from":{"title":"From"},"to":{"title":"To"}},"additionalProperties":true,"type":"object","required":["from","to"],"title":"PublicInlineGraphConnection"},"PublicInlineGraphNode":{"properties":{"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"inputs":{"additionalProperties":true,"type":"object","title":"Inputs"},"position":{"anyOf":[{"$ref":"#/components/schemas/PublicInlineGraphPosition"},{"type":"null"}]}},"additionalProperties":true,"type":"object","required":["id","type"],"title":"PublicInlineGraphNode"},"PublicInlineGraphPosition":{"properties":{"x":{"anyOf":[{"type":"number"},{"type":"integer"}],"title":"X"},"y":{"anyOf":[{"type":"number"},{"type":"integer"}],"title":"Y"}},"additionalProperties":true,"type":"object","required":["x","y"],"title":"PublicInlineGraphPosition"},"PublicListResponse_PublicNodeTypeSummary_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/PublicNodeTypeSummary"},"type":"array","title":"Data","description":"Items returned for this page."},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextcursor","description":"Opaque cursor for the next page. Omitted when there are no more results.","examples":["eyJzb3J0IjoidXBkYXRlZEF0OmRlc2MsaWQ6ZGVzYyJ9"]},"hasMore":{"type":"boolean","title":"Hasmore","description":"True when another page is available."}},"type":"object","required":["data","hasMore"],"title":"PublicListResponse[PublicNodeTypeSummary]","example":{"data":[],"hasMore":false}},"PublicListResponse_PublicProjectSummary_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/PublicProjectSummary"},"type":"array","title":"Data","description":"Items returned for this page."},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextcursor","description":"Opaque cursor for the next page. Omitted when there are no more results.","examples":["eyJzb3J0IjoidXBkYXRlZEF0OmRlc2MsaWQ6ZGVzYyJ9"]},"hasMore":{"type":"boolean","title":"Hasmore","description":"True when another page is available."}},"type":"object","required":["data","hasMore"],"title":"PublicListResponse[PublicProjectSummary]","example":{"data":[],"hasMore":false}},"PublicListResponse_PublicRunEvent_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/PublicRunEvent"},"type":"array","title":"Data","description":"Items returned for this page."},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextcursor","description":"Opaque cursor for the next page. Omitted when there are no more results.","examples":["eyJzb3J0IjoidXBkYXRlZEF0OmRlc2MsaWQ6ZGVzYyJ9"]},"hasMore":{"type":"boolean","title":"Hasmore","description":"True when another page is available."}},"type":"object","required":["data","hasMore"],"title":"PublicListResponse[PublicRunEvent]","example":{"data":[],"hasMore":false}},"PublicListResponse_PublicTemplateEndpointSummary_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/PublicTemplateEndpointSummary"},"type":"array","title":"Data","description":"Items returned for this page."},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextcursor","description":"Opaque cursor for the next page. Omitted when there are no more results.","examples":["eyJzb3J0IjoidXBkYXRlZEF0OmRlc2MsaWQ6ZGVzYyJ9"]},"hasMore":{"type":"boolean","title":"Hasmore","description":"True when another page is available."}},"type":"object","required":["data","hasMore"],"title":"PublicListResponse[PublicTemplateEndpointSummary]","example":{"data":[],"hasMore":false}},"PublicListResponse_PublicTemplateSummary_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/PublicTemplateSummary"},"type":"array","title":"Data","description":"Items returned for this page."},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nextcursor","description":"Opaque cursor for the next page. Omitted when there are no more results.","examples":["eyJzb3J0IjoidXBkYXRlZEF0OmRlc2MsaWQ6ZGVzYyJ9"]},"hasMore":{"type":"boolean","title":"Hasmore","description":"True when another page is available."}},"type":"object","required":["data","hasMore"],"title":"PublicListResponse[PublicTemplateSummary]","example":{"data":[],"hasMore":false}},"PublicMultipartUploadPart":{"properties":{"partNumber":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Partnumber"},"etag":{"type":"string","minLength":1,"title":"Etag"}},"type":"object","required":["partNumber","etag"],"title":"PublicMultipartUploadPart"},"PublicNodePin":{"properties":{"name":{"type":"string","title":"Name","description":"Pin name as defined by the node.","examples":["prompt"]},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type","description":"Public data type for the pin.","examples":["string"]},"value":{"anyOf":[{},{"type":"null"}],"title":"Value","description":"Current primitive value, if exposed and serializable."},"exposed":{"type":"boolean","title":"Exposed","description":"Whether the pin is exposed as a public input/output.","default":false},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","description":"Human-readable pin label.","examples":["Prompt"]}},"type":"object","required":["name"],"title":"PublicNodePin","example":{"exposed":true,"label":"Prompt","name":"prompt","type":"string","value":"A cinematic wide shot"}},"PublicNodeTypeDetail":{"properties":{"type":{"type":"string","title":"Type","description":"Node type identifier.","examples":["builtin/image/load_image"]},"title":{"type":"string","title":"Title","description":"Node display title.","examples":["Load Image"]},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","description":"Node category.","examples":["Image"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Short description of what the node does."},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon","description":"Icon identifier used by the UI.","examples":["image"]},"thumbnailUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnailurl","description":"Short-lived signed URL for the node catalog thumbnail, when available."},"thumbnailExpiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Thumbnailexpiresat","description":"Expiration timestamp for thumbnailUrl, when present."},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"Search and discovery tags.","examples":[["image","loader"]]},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"Source namespace for the node type.","examples":["builtin"]},"inputs":{"items":{"$ref":"#/components/schemas/PublicNodeTypePin"},"type":"array","title":"Inputs","description":"Input pins exposed by this node type."},"outputs":{"items":{"$ref":"#/components/schemas/PublicNodeTypePin"},"type":"array","title":"Outputs","description":"Output pins exposed by this node type."}},"type":"object","required":["type","title"],"title":"PublicNodeTypeDetail","example":{"category":"Image","description":"Load an image file into the graph.","icon":"image","inputs":[{"exposed":true,"label":"Image","name":"path","type":"file"}],"outputs":[{"exposed":false,"label":"Image","name":"image","type":"image"}],"source":"builtin","tags":["image","loader"],"title":"Load Image","type":"builtin/image/load_image"}},"PublicNodeTypePin":{"properties":{"name":{"type":"string","title":"Name","description":"Pin name defined by the node type.","examples":["prompt"]},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type","description":"Pin data type.","examples":["string"]},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","description":"Human-readable pin label.","examples":["Prompt"]},"default":{"anyOf":[{},{"type":"null"}],"title":"Default","description":"Default value for the pin, when available."},"exposed":{"type":"boolean","title":"Exposed","description":"Whether this pin is intended for public interaction.","default":false}},"type":"object","required":["name"],"title":"PublicNodeTypePin","example":{"default":"","exposed":true,"label":"Prompt","name":"prompt","type":"string"}},"PublicNodeTypeSummary":{"properties":{"type":{"type":"string","title":"Type","description":"Node type identifier.","examples":["builtin/image/load_image"]},"title":{"type":"string","title":"Title","description":"Node display title.","examples":["Load Image"]},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","description":"Node category.","examples":["Image"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Short description of what the node does."},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon","description":"Icon identifier used by the UI.","examples":["image"]},"thumbnailUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnailurl","description":"Short-lived signed URL for the node catalog thumbnail, when available."},"thumbnailExpiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Thumbnailexpiresat","description":"Expiration timestamp for thumbnailUrl, when present."},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"Search and discovery tags.","examples":[["image","loader"]]},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"Source namespace for the node type.","examples":["builtin"]}},"type":"object","required":["type","title"],"title":"PublicNodeTypeSummary","example":{"category":"Image","description":"Load an image file into the graph.","icon":"image","source":"builtin","tags":["image","loader"],"title":"Load Image","type":"builtin/image/load_image"}},"PublicPosition":{"properties":{"x":{"type":"number","title":"X","description":"Node X position on the graph canvas.","examples":[120.0]},"y":{"type":"number","title":"Y","description":"Node Y position on the graph canvas.","examples":[240.0]},"z":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Z","description":"Optional Z position for surfaces that support it.","examples":[0.0]}},"type":"object","required":["x","y"],"title":"PublicPosition","example":{"x":120.0,"y":240.0}},"PublicPrimitiveOutput":{"properties":{"type":{"type":"string","enum":["string","number","boolean","json","null"],"title":"Type"},"value":{"title":"Value"}},"type":"object","required":["type","value"],"title":"PublicPrimitiveOutput"},"PublicProjectCreateRequest":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name","default":"Untitled Project"},"externalId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalid"},"externalUserId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externaluserid"},"externalWorkspaceId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalworkspaceid"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata","description":"Developer-defined metadata stored for correlation. Not filterable unless promoted to an indexed field."}},"type":"object","title":"PublicProjectCreateRequest","example":{"externalId":"workspace_123","externalUserId":"user_789","externalWorkspaceId":"team_456","metadata":{"plan":"pro"},"name":"Jane's Workspace"}},"PublicProjectDetail":{"properties":{"id":{"type":"string","title":"Id","description":"Stable project identifier.","examples":["proj_123"]},"name":{"type":"string","title":"Name","description":"Project display name.","examples":["Machine"]},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalid","description":"Developer-provided external project/workspace identifier.","examples":["workspace_123"]},"externalUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externaluserid","description":"Developer-provided identifier for the developer's own end user.","examples":["user_789"]},"externalWorkspaceId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalworkspaceid","description":"Developer-provided identifier for the developer's own workspace/team.","examples":["team_456"]},"nodeCount":{"type":"integer","title":"Nodecount","description":"Number of nodes in the project graph.","examples":[12]},"createdAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Createdat","description":"Project creation timestamp, when available.","examples":["2026-05-21T14:21:52.152049+00:00"]},"updatedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updatedat","description":"Most recent project update timestamp, when available.","examples":["2026-05-21T15:10:03.000000+00:00"]},"thumbnailUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnailurl","description":"Short-lived signed thumbnail URL, when a project thumbnail is available.","examples":[null]},"thumbnailExpiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Thumbnailexpiresat","description":"Expiration timestamp for thumbnailUrl, when present.","examples":[null]},"version":{"type":"integer","title":"Version","description":"Optimistic concurrency version for the project.","examples":[7]}},"type":"object","required":["id","name","nodeCount","version"],"title":"PublicProjectDetail","example":{"createdAt":"2026-05-21T14:21:52.152049+00:00","externalId":"workspace_123","externalUserId":"user_789","externalWorkspaceId":"team_456","id":"proj_123","name":"Machine","nodeCount":12,"updatedAt":"2026-05-21T15:10:03.000000+00:00","version":7}},"PublicProjectDocument":{"properties":{"projectId":{"type":"string","title":"Projectid","description":"Stable project identifier.","examples":["proj_123"]},"version":{"type":"integer","title":"Version","description":"Optimistic concurrency version for the project.","examples":[7]},"name":{"type":"string","title":"Name","description":"Project display name.","examples":["Machine"]},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata","description":"Developer-defined project metadata."},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalid","description":"Developer-provided external project/workspace identifier."},"externalUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externaluserid","description":"Developer-provided end-user identifier."},"externalWorkspaceId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalworkspaceid","description":"Developer-provided workspace/team identifier."},"document":{"$ref":"#/components/schemas/PublicProjectDocumentBody-Output","description":"Editable project document sections."},"warnings":{"items":{"$ref":"#/components/schemas/PublicProjectDocumentWarning"},"type":"array","title":"Warnings","description":"Non-fatal normalization warnings, such as redacted file inputs."},"createdAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Createdat","description":"Project creation timestamp, when available."},"updatedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updatedat","description":"Most recent project update timestamp, when available."}},"type":"object","required":["projectId","version","name","document"],"title":"PublicProjectDocument","example":{"createdAt":"2026-05-21T14:21:52.152049+00:00","document":{"graph":{"connections":[{"from":["node_123","text"],"to":["node_456","prompt"]}],"nodes":[{"id":"node_123","inputs":{"inputPrompt":{"type":"string","value":"A cinematic wide shot"}},"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"}]}},"externalId":"workspace_123","externalUserId":"user_789","externalWorkspaceId":"team_456","metadata":{"plan":"pro"},"name":"Machine","projectId":"proj_123","updatedAt":"2026-05-21T15:10:03.000000+00:00","version":7,"warnings":[]}},"PublicProjectDocumentBody-Input":{"properties":{"graph":{"$ref":"#/components/schemas/PublicEditableGraph-Input","description":"Editable project graph."}},"type":"object","required":["graph"],"title":"PublicProjectDocumentBody","example":{"graph":{"connections":[{"from":["node_123","text"],"to":["node_456","prompt"]}],"nodes":[{"id":"node_123","inputs":{"inputPrompt":{"type":"string","value":"A cinematic wide shot"}},"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"}]}}},"PublicProjectDocumentBody-Output":{"properties":{"graph":{"$ref":"#/components/schemas/PublicEditableGraph-Output","description":"Editable project graph."}},"type":"object","required":["graph"],"title":"PublicProjectDocumentBody","example":{"graph":{"connections":[{"from":["node_123","text"],"to":["node_456","prompt"]}],"nodes":[{"id":"node_123","inputs":{"inputPrompt":{"type":"string","value":"A cinematic wide shot"}},"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"}]}}},"PublicProjectDocumentPatchOperation":{"properties":{"op":{"type":"string","title":"Op","description":"Semantic operation name. updateNode.inputs replaces the node's public input map wholesale; use setNodeInput/unsetNodeInput for single-pin edits.","examples":["addNode"]}},"additionalProperties":true,"type":"object","required":["op"],"title":"PublicProjectDocumentPatchOperation","example":{"input":"prompt","nodeId":"node_123","op":"setNodeInput","value":{"type":"string","value":"A quieter variation"}}},"PublicProjectDocumentPatchRequest":{"properties":{"expectedVersion":{"type":"integer","minimum":0.0,"title":"Expectedversion","description":"Last project version observed by the client."},"operations":{"items":{"$ref":"#/components/schemas/PublicProjectDocumentPatchOperation"},"type":"array","maxItems":100,"minItems":1,"title":"Operations","description":"Ordered semantic document operations to apply atomically."}},"type":"object","required":["expectedVersion","operations"],"title":"PublicProjectDocumentPatchRequest","example":{"expectedVersion":7,"operations":[{"node":{"id":"node_123","inputs":{"inputPrompt":{"type":"string","value":"A cinematic wide shot"}},"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"},"op":"addNode"},{"from":["node_123","outputPrompt"],"op":"connect","to":["node_456","inputPrompt"]}]}},"PublicProjectDocumentPatchResponse":{"properties":{"projectId":{"type":"string","title":"Projectid","description":"Stable project identifier.","examples":["proj_123"]},"version":{"type":"integer","title":"Version","description":"Optimistic concurrency version for the project.","examples":[7]},"name":{"type":"string","title":"Name","description":"Project display name.","examples":["Machine"]},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata","description":"Developer-defined project metadata."},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalid","description":"Developer-provided external project/workspace identifier."},"externalUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externaluserid","description":"Developer-provided end-user identifier."},"externalWorkspaceId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalworkspaceid","description":"Developer-provided workspace/team identifier."},"document":{"$ref":"#/components/schemas/PublicProjectDocumentBody-Output","description":"Editable project document sections."},"warnings":{"items":{"$ref":"#/components/schemas/PublicProjectDocumentWarning"},"type":"array","title":"Warnings","description":"Non-fatal normalization warnings, such as redacted file inputs."},"createdAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Createdat","description":"Project creation timestamp, when available."},"updatedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updatedat","description":"Most recent project update timestamp, when available."},"appliedOperations":{"type":"integer","title":"Appliedoperations","description":"Number of semantic operations applied.","examples":[2]}},"type":"object","required":["projectId","version","name","document","appliedOperations"],"title":"PublicProjectDocumentPatchResponse","example":{"createdAt":"2026-05-21T14:21:52.152049+00:00","document":{"graph":{"connections":[{"from":["node_123","text"],"to":["node_456","prompt"]}],"nodes":[{"id":"node_123","inputs":{"inputPrompt":{"type":"string","value":"A cinematic wide shot"}},"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"}]}},"externalId":"workspace_123","externalUserId":"user_789","externalWorkspaceId":"team_456","metadata":{"plan":"pro"},"name":"Machine","projectId":"proj_123","updatedAt":"2026-05-21T15:10:03.000000+00:00","version":7,"warnings":[]}},"PublicProjectDocumentReplaceRequest":{"properties":{"expectedVersion":{"type":"integer","minimum":0.0,"title":"Expectedversion","description":"Last project version observed by the client."},"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"externalId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalid"},"externalUserId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externaluserid"},"externalWorkspaceId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalworkspaceid"},"document":{"$ref":"#/components/schemas/PublicProjectDocumentBody-Input","description":"Replacement editable project document sections."}},"type":"object","required":["expectedVersion","document"],"title":"PublicProjectDocumentReplaceRequest","example":{"document":{"graph":{"connections":[{"from":["node_123","text"],"to":["node_456","prompt"]}],"nodes":[{"id":"node_123","inputs":{"inputPrompt":{"type":"string","value":"A cinematic wide shot"}},"position":{"x":120.0,"y":240.0},"title":"Text Prompt","type":"builtin/utils/text_prompt"}]}},"expectedVersion":7,"metadata":{"plan":"pro"},"name":"Machine"}},"PublicProjectDocumentWarning":{"properties":{"code":{"type":"string","title":"Code","description":"Stable warning code.","examples":["FILE_INPUT_VALUE_REDACTED"]},"message":{"type":"string","title":"Message","description":"Human-readable warning message."},"path":{"type":"string","title":"Path","description":"Path to the affected public document field.","examples":["document.graph.nodes.node-a.inputs.inputImage.value"]}},"type":"object","required":["code","message","path"],"title":"PublicProjectDocumentWarning","example":{"code":"FILE_INPUT_VALUE_REDACTED","message":"File-like input value was redacted because it is not a public REST file reference.","path":"document.graph.nodes.node-a.inputs.inputImage.value"}},"PublicProjectSpendNode":{"properties":{"nodeId":{"type":"string","title":"Nodeid","description":"Node instance identifier.","examples":["node_456"]},"nodeType":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nodetype","description":"Node type identifier.","examples":["builtin/image/generate"]},"nodeTitle":{"type":"string","title":"Nodetitle","description":"Node display title.","examples":["Generate Image"]},"credits":{"type":"integer","title":"Credits","description":"Credits billed for this node.","examples":[24]},"microcredits":{"type":"string","title":"Microcredits","description":"Exact billed amount in millionths of one credit.","examples":["24110000"]},"billedRuns":{"type":"integer","title":"Billedruns","description":"Number of billed node executions counted for this node.","examples":[2]},"lastUsedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Lastusedat","description":"Timestamp of the most recent billed node execution.","examples":["2026-05-24T12:00:00Z"]}},"type":"object","required":["nodeId","nodeTitle","credits","microcredits","billedRuns"],"title":"PublicProjectSpendNode"},"PublicProjectSpendRun":{"properties":{"id":{"type":"string","title":"Id","description":"Stable row identifier for this billed run entry.","examples":["tx_123"]},"credits":{"type":"integer","title":"Credits","description":"Net credits billed for this node execution.","examples":[12]},"microcredits":{"type":"string","title":"Microcredits","description":"Exact net billed amount in millionths of one credit.","examples":["12110000"]},"kind":{"type":"string","title":"Kind","description":"Entry kind. Project spend exposes net billed deductions.","default":"deduction"},"chargeType":{"type":"string","title":"Chargetype","description":"Primary charge type for this billed run.","examples":["provider"]},"reason":{"type":"string","title":"Reason","description":"Reason/source for this spend row.","examples":["node_history"]},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider","description":"Primary provider, when available.","examples":["fal"]},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"Model billed for assistant/API-backed rows, when available.","examples":["anthropic/claude-sonnet-5"]},"nodeId":{"type":"string","title":"Nodeid","description":"Node instance identifier.","examples":["node_456"]},"nodeType":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nodetype","description":"Node type identifier.","examples":["builtin/image/generate"]},"nodeTitle":{"type":"string","title":"Nodetitle","description":"Node display title.","examples":["Generate Image"]},"nodeExecutionId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nodeexecutionid","description":"Node execution identifier.","examples":["nexec_abc"]},"createdAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Createdat","description":"Node execution timestamp."}},"type":"object","required":["id","credits","microcredits","chargeType","reason","nodeId","nodeTitle"],"title":"PublicProjectSpendRun"},"PublicProjectSpendSummary":{"properties":{"projectId":{"type":"string","title":"Projectid","description":"Project identifier.","examples":["project_123"]},"totalCredits":{"type":"integer","title":"Totalcredits","description":"Whole billed credits derived from project-attributed ledger transactions.","examples":[42]},"totalMicrocredits":{"type":"string","title":"Totalmicrocredits","description":"Exact total billed amount in millionths of one credit.","examples":["42110000"]},"byNode":{"items":{"$ref":"#/components/schemas/PublicProjectSpendNode"},"type":"array","title":"Bynode","description":"Spend grouped by node."},"byProvider":{"additionalProperties":{"type":"integer"},"type":"object","title":"Byprovider","description":"Provider credit breakdown."},"byProviderMicrocredits":{"additionalProperties":{"type":"string"},"type":"object","title":"Byprovidermicrocredits","description":"Exact provider breakdown in millionths of one credit."},"byChargeType":{"additionalProperties":{"type":"integer"},"type":"object","title":"Bychargetype","description":"Charge type credit breakdown."},"byChargeTypeMicrocredits":{"additionalProperties":{"type":"string"},"type":"object","title":"Bychargetypemicrocredits","description":"Exact charge-type breakdown in millionths of one credit."},"recentRuns":{"items":{"$ref":"#/components/schemas/PublicProjectSpendRun"},"type":"array","title":"Recentruns","description":"Recent billed executions derived from ledger transactions."}},"type":"object","required":["projectId","totalCredits","totalMicrocredits","byNode","byProvider","byProviderMicrocredits","byChargeType","byChargeTypeMicrocredits","recentRuns"],"title":"PublicProjectSpendSummary","example":{"byChargeType":{"provider":24},"byChargeTypeMicrocredits":{"provider":"24110000"},"byNode":[{"billedRuns":2,"credits":24,"lastUsedAt":"2026-05-24T12:00:00Z","microcredits":"24110000","nodeId":"node_456","nodeTitle":"Generate Image","nodeType":"builtin/image/generate"}],"byProvider":{"fal":24},"byProviderMicrocredits":{"fal":"24110000"},"projectId":"project_123","recentRuns":[],"totalCredits":42,"totalMicrocredits":"42110000"}},"PublicProjectStoryboard":{"properties":{"projectId":{"type":"string","title":"Projectid","description":"Stable project identifier.","examples":["proj_123"]},"version":{"type":"integer","title":"Version","description":"Optimistic concurrency version for the project.","examples":[7]},"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Project storyboard exported as Kaitoi Storyboard Document v1."},"summary":{"$ref":"#/components/schemas/PublicStoryboardSummary","description":"Counts derived from the exported document."}},"type":"object","required":["projectId","version","document","summary"],"title":"PublicProjectStoryboard","example":{"document":{"kaitoiType":"storyboard","name":"Storyboard","sequences":[{"id":"scene-1","name":"Scene 1","order":0,"shots":[{"description":"A quiet establishing shot.","durationSeconds":3,"id":"frame-1","order":0,"transition":"cut"}]}],"settings":{"aspectRatio":"16:9","defaultFrameDuration":3},"version":1},"projectId":"proj_123","summary":{"mediaCount":0,"sceneCount":1,"shotCount":1},"version":7}},"PublicProjectStoryboardApplyResponse":{"properties":{"projectId":{"type":"string","title":"Projectid","description":"Stable project identifier.","examples":["proj_123"]},"version":{"type":"integer","title":"Version","description":"New optimistic concurrency version after the write.","examples":[8]},"mode":{"type":"string","enum":["replace","append"],"title":"Mode","description":"Apply mode used for this write."},"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Resulting project storyboard exported as Kaitoi Storyboard Document v1."},"summary":{"$ref":"#/components/schemas/PublicStoryboardApplySummary","description":"Counts and warnings from the apply operation."}},"type":"object","required":["projectId","version","mode","document","summary"],"title":"PublicProjectStoryboardApplyResponse","example":{"document":{"kaitoiType":"storyboard","name":"Storyboard","sequences":[{"id":"scene-1","name":"Scene 1","order":0,"shots":[{"description":"A quiet establishing shot.","durationSeconds":3,"id":"frame-1","order":0,"transition":"cut"}]}],"settings":{"aspectRatio":"16:9","defaultFrameDuration":3},"version":1},"mode":"replace","projectId":"proj_123","summary":{"documentMedia":0,"extraPanelMedia":0,"mediaCount":12,"mediaImported":12,"mediaSkipped":0,"sceneCount":1,"shotCount":12,"unresolvedMedia":0,"urlMedia":0,"warnings":[]},"version":8}},"PublicProjectStoryboardReplaceRequest":{"properties":{"expectedVersion":{"type":"integer","minimum":0.0,"title":"Expectedversion","description":"Last project version observed by the client."},"mode":{"type":"string","enum":["replace","append"],"title":"Mode","description":"How to apply the storyboard document to the current project storyboard.","default":"replace"},"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Kaitoi Storyboard Document v1 JSON to apply."}},"type":"object","required":["expectedVersion","document"],"title":"PublicProjectStoryboardReplaceRequest","example":{"document":{"kaitoiType":"storyboard","name":"Storyboard","sequences":[{"id":"scene-1","name":"Scene 1","order":0,"shots":[{"description":"A quiet establishing shot.","durationSeconds":3,"id":"frame-1","order":0,"transition":"cut"}]}],"settings":{"aspectRatio":"16:9","defaultFrameDuration":3},"version":1},"expectedVersion":7,"mode":"replace"}},"PublicProjectSummary":{"properties":{"id":{"type":"string","title":"Id","description":"Stable project identifier.","examples":["proj_123"]},"name":{"type":"string","title":"Name","description":"Project display name.","examples":["Machine"]},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalid","description":"Developer-provided external project/workspace identifier.","examples":["workspace_123"]},"externalUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externaluserid","description":"Developer-provided identifier for the developer's own end user.","examples":["user_789"]},"externalWorkspaceId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalworkspaceid","description":"Developer-provided identifier for the developer's own workspace/team.","examples":["team_456"]},"nodeCount":{"type":"integer","title":"Nodecount","description":"Number of nodes in the project graph.","examples":[12]},"createdAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Createdat","description":"Project creation timestamp, when available.","examples":["2026-05-21T14:21:52.152049+00:00"]},"updatedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updatedat","description":"Most recent project update timestamp, when available.","examples":["2026-05-21T15:10:03.000000+00:00"]},"thumbnailUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnailurl","description":"Short-lived signed thumbnail URL, when a project thumbnail is available.","examples":[null]},"thumbnailExpiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Thumbnailexpiresat","description":"Expiration timestamp for thumbnailUrl, when present.","examples":[null]}},"type":"object","required":["id","name","nodeCount"],"title":"PublicProjectSummary","example":{"createdAt":"2026-05-21T14:21:52.152049+00:00","externalId":"workspace_123","externalUserId":"user_789","externalWorkspaceId":"team_456","id":"proj_123","name":"Machine","nodeCount":12,"updatedAt":"2026-05-21T15:10:03.000000+00:00"}},"PublicProjectTimeline":{"properties":{"projectId":{"type":"string","title":"Projectid","description":"Stable project identifier.","examples":["proj_123"]},"version":{"type":"integer","title":"Version","description":"Optimistic concurrency version for the project.","examples":[7]},"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Project timeline exported as Kaitoi Timeline Document v1."},"summary":{"$ref":"#/components/schemas/PublicTimelineSummary","description":"Counts derived from the exported document."}},"type":"object","required":["projectId","version","document","summary"],"title":"PublicProjectTimeline","example":{"document":{"kaitoiType":"timeline","name":"Timeline","timeline":{"clips":[{"duration":3,"filename":"hero.png","id":"clip-1","name":"Hero","opacity":100,"startTime":0,"storageType":"data","trackId":"track-1","transform":{"rotation":0,"scale":100,"x":0,"y":0},"trimEnd":0,"trimStart":0,"type":"image","volume":100}],"currentTime":0,"frameRate":30,"playheadPosition":0,"projectDuration":60,"projectResolution":{"height":1080,"isAutoDetected":true,"width":1920},"selectedClipIds":[],"selectedTrackId":"track-1","tracks":[{"height":60,"id":"track-1","locked":false,"mutedAudio":false,"mutedVideo":false,"name":"Track 1","volume":1}],"zoom":100},"version":1},"projectId":"proj_123","summary":{"clipCount":1,"durationSeconds":60,"trackCount":1},"version":7}},"PublicProjectTimelineApplyResponse":{"properties":{"projectId":{"type":"string","title":"Projectid","description":"Stable project identifier.","examples":["proj_123"]},"version":{"type":"integer","title":"Version","description":"New optimistic concurrency version after the write.","examples":[8]},"mode":{"type":"string","const":"replace","title":"Mode","description":"Apply mode used for this write."},"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Resulting project timeline exported as Kaitoi Timeline Document v1."},"summary":{"$ref":"#/components/schemas/PublicTimelineSummary","description":"Counts derived from the saved timeline document."}},"type":"object","required":["projectId","version","mode","document","summary"],"title":"PublicProjectTimelineApplyResponse","example":{"document":{"kaitoiType":"timeline","name":"Timeline","timeline":{"clips":[{"duration":3,"filename":"hero.png","id":"clip-1","name":"Hero","opacity":100,"startTime":0,"storageType":"data","trackId":"track-1","transform":{"rotation":0,"scale":100,"x":0,"y":0},"trimEnd":0,"trimStart":0,"type":"image","volume":100}],"currentTime":0,"frameRate":30,"playheadPosition":0,"projectDuration":60,"projectResolution":{"height":1080,"isAutoDetected":true,"width":1920},"selectedClipIds":[],"selectedTrackId":"track-1","tracks":[{"height":60,"id":"track-1","locked":false,"mutedAudio":false,"mutedVideo":false,"name":"Track 1","volume":1}],"zoom":100},"version":1},"mode":"replace","projectId":"proj_123","summary":{"clipCount":1,"durationSeconds":60,"trackCount":1},"version":8}},"PublicProjectTimelineReplaceRequest":{"properties":{"expectedVersion":{"type":"integer","minimum":0.0,"title":"Expectedversion","description":"Last project version observed by the client."},"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Kaitoi Timeline Document v1 JSON to apply."}},"type":"object","required":["expectedVersion","document"],"title":"PublicProjectTimelineReplaceRequest","example":{"document":{"kaitoiType":"timeline","name":"Timeline","timeline":{"clips":[{"duration":3,"filename":"hero.png","id":"clip-1","name":"Hero","opacity":100,"startTime":0,"storageType":"data","trackId":"track-1","transform":{"rotation":0,"scale":100,"x":0,"y":0},"trimEnd":0,"trimStart":0,"type":"image","volume":100}],"currentTime":0,"frameRate":30,"playheadPosition":0,"projectDuration":60,"projectResolution":{"height":1080,"isAutoDetected":true,"width":1920},"selectedClipIds":[],"selectedTrackId":"track-1","tracks":[{"height":60,"id":"track-1","locked":false,"mutedAudio":false,"mutedVideo":false,"name":"Track 1","volume":1}],"zoom":100},"version":1},"expectedVersion":7}},"PublicProjectUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name"},"externalId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalid"},"externalUserId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externaluserid"},"externalWorkspaceId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalworkspaceid"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"},"expectedVersion":{"type":"integer","minimum":0.0,"title":"Expectedversion","description":"Last project version observed by the client."}},"type":"object","required":["expectedVersion"],"title":"PublicProjectUpdateRequest","example":{"expectedVersion":1,"externalUserId":"user_789","metadata":{"plan":"enterprise"},"name":"Jane's Renamed Workspace"}},"PublicProjectedNodePin":{"properties":{"name":{"type":"string","title":"Name","description":"Pin name as defined by the placed node.","examples":["inputImage"]},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type","description":"Public data type for the pin.","examples":["image"]}},"type":"object","required":["name"],"title":"PublicProjectedNodePin"},"PublicRunApplyOutputsRequest":{"properties":{"expectedVersion":{"type":"integer","minimum":0.0,"title":"Expectedversion","description":"Project version the run was created from. Applying outputs fails if the saved project changed after the run was created."},"outputKeys":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":256},{"type":"null"}],"title":"Outputkeys","description":"Optional subset of run output keys to persist. Omit to apply all outputs recorded on the succeeded saved-project run."}},"type":"object","required":["expectedVersion"],"title":"PublicRunApplyOutputsRequest"},"PublicRunApplyOutputsResponse":{"properties":{"runId":{"type":"string","title":"Runid"},"projectId":{"type":"string","title":"Projectid"},"version":{"type":"integer","minimum":0.0,"title":"Version","description":"New saved project version after applying outputs."},"appliedOutputs":{"type":"integer","minimum":0.0,"title":"Appliedoutputs","description":"Number of run outputs applied to the project."},"outputKeys":{"items":{"type":"string"},"type":"array","title":"Outputkeys","description":"Run output keys applied to the saved project."}},"type":"object","required":["runId","projectId","version","appliedOutputs","outputKeys"],"title":"PublicRunApplyOutputsResponse"},"PublicRunBooleanInput":{"properties":{"type":{"type":"string","const":"boolean","title":"Type"},"value":{"type":"boolean","title":"Value"}},"type":"object","required":["type","value"],"title":"PublicRunBooleanInput"},"PublicRunCreateRequest":{"properties":{"projectId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Projectid","description":"Project id to snapshot and execute."},"graph":{"anyOf":[{"$ref":"#/components/schemas/PublicInlineGraph"},{"type":"null"}],"description":"Inline transient graph to snapshot and execute instead of a saved project."},"targetNodeIds":{"items":{"type":"string"},"type":"array","title":"Targetnodeids","description":"Node ids to execute. Empty means the service may choose the saved-project default target. Inline graph runs must provide at least one target node id."},"externalId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalid"},"externalUserId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externaluserid","description":"Developer end-user guard. Referenced files with externalUserId must match this value."},"externalWorkspaceId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalworkspaceid"},"inputOverrides":{"additionalProperties":{"additionalProperties":{"oneOf":[{"$ref":"#/components/schemas/PublicRunFileInput"},{"$ref":"#/components/schemas/PublicRunStringInput"},{"$ref":"#/components/schemas/PublicRunNumberInput"},{"$ref":"#/components/schemas/PublicRunBooleanInput"},{"$ref":"#/components/schemas/PublicRunJsonInput"},{"$ref":"#/components/schemas/PublicRunNullInput"}],"discriminator":{"propertyName":"type","mapping":{"boolean":"#/components/schemas/PublicRunBooleanInput","file":"#/components/schemas/PublicRunFileInput","json":"#/components/schemas/PublicRunJsonInput","null":"#/components/schemas/PublicRunNullInput","number":"#/components/schemas/PublicRunNumberInput","string":"#/components/schemas/PublicRunStringInput"}}},"type":"object"},"type":"object","title":"Inputoverrides","description":"Non-persistent input overrides keyed by node id then input pin name."},"persistInputOverrides":{"type":"boolean","title":"Persistinputoverrides","description":"Reserved for a later persistence contract. V1 run overrides default to non-persistent.","default":false}},"type":"object","title":"PublicRunCreateRequest","examples":[{"summary":"Saved project run","value":{"externalUserId":"user_789","inputOverrides":{"node_456":{"inputImage":{"fileId":"2f8f8c5df80e4f76a5b7d1bbd6fae0ab.png","type":"file"},"prompt":{"type":"string","value":"Describe this image"}}},"projectId":"project_123","targetNodeIds":["node_456"]}},{"summary":"Inline graph run","value":{"externalUserId":"user_789","graph":{"connections":[{"from":["prompt","outputPrompt"],"to":["echo","inputText"]}],"nodes":[{"id":"prompt","inputs":{"inputPrompt":{"type":"string","value":"Write a short caption"}},"position":{"x":0,"y":0},"title":"Prompt","type":"builtin/utils/text_prompt"},{"id":"echo","inputs":{},"position":{"x":360,"y":0},"type":"builtin/utils/text"}]},"targetNodeIds":["echo"]}}],"example":{"externalUserId":"user_789","inputOverrides":{"node_456":{"inputImage":{"fileId":"2f8f8c5df80e4f76a5b7d1bbd6fae0ab.png","type":"file"},"prompt":{"type":"string","value":"Describe this image"}}},"projectId":"project_123","targetNodeIds":["node_456"]}},"PublicRunDetail":{"properties":{"id":{"type":"string","title":"Id"},"sourceType":{"type":"string","enum":["project","inline_graph"],"title":"Sourcetype","default":"project"},"projectId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Projectid"},"projectVersion":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Projectversion"},"status":{"type":"string","enum":["accepted","queued","running","succeeded","failed","canceled"],"title":"Status"},"cancelRequested":{"type":"boolean","title":"Cancelrequested","default":false},"targetNodeIds":{"items":{"type":"string"},"type":"array","title":"Targetnodeids"},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalid"},"externalUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externaluserid"},"externalWorkspaceId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalworkspaceid"},"inputFiles":{"items":{"$ref":"#/components/schemas/PublicRunFileInputReference"},"type":"array","title":"Inputfiles"},"outputs":{"additionalProperties":{"oneOf":[{"$ref":"#/components/schemas/PublicFileOutput"},{"$ref":"#/components/schemas/PublicPrimitiveOutput"}],"discriminator":{"propertyName":"type","mapping":{"boolean":"#/components/schemas/PublicPrimitiveOutput","file":"#/components/schemas/PublicFileOutput","json":"#/components/schemas/PublicPrimitiveOutput","null":"#/components/schemas/PublicPrimitiveOutput","number":"#/components/schemas/PublicPrimitiveOutput","string":"#/components/schemas/PublicPrimitiveOutput"}}},"type":"object","title":"Outputs"},"error":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Error"},"creditsUsed":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Creditsused","description":"Credits charged by this run. Null while the run is active, or when a terminal run could not produce a reliable accounting summary."},"creditsUsedMicrocredits":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Creditsusedmicrocredits","description":"Exact run charge in millionths of one credit."},"spend":{"anyOf":[{"$ref":"#/components/schemas/PublicRunSpendSummary"},{"type":"null"}],"description":"Compact spend summary for this run, populated from node execution cost snapshots when the run reaches a terminal state."},"executionTimeMs":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Executiontimems"},"createdAt":{"type":"string","format":"date-time","title":"Createdat"},"updatedAt":{"type":"string","format":"date-time","title":"Updatedat"}},"type":"object","required":["id","status","createdAt","updatedAt"],"title":"PublicRunDetail","example":{"createdAt":"2026-01-01T00:00:00Z","creditsUsed":12,"executionTimeMs":2143,"id":"run_abc123","outputs":{"outputImage":{"contentType":"image/png","downloadUrl":"https://files.example/d/2f8f8c5df80e4f76a5b7d1bbd6fae0ab.png?sig=...","fileId":"2f8f8c5df80e4f76a5b7d1bbd6fae0ab.png","filename":"random_image.png","previewUrl":"https://files.example/p/2f8f8c5df80e4f76a5b7d1bbd6fae0ab.png?sig=...","sizeBytes":482931,"type":"file"}},"sourceType":"inline_graph","spend":{"byChargeType":{"provider":12},"byNode":[{"billedRuns":1,"credits":12,"nodeId":"image","nodeTitle":"Generate Image","nodeType":"builtin/image/generate"}],"byProvider":{"fal":12},"totalCredits":12},"status":"succeeded","targetNodeIds":["image"],"updatedAt":"2026-01-01T00:00:03Z"}},"PublicRunEvent":{"properties":{"id":{"type":"string","title":"Id"},"runId":{"type":"string","title":"Runid"},"type":{"type":"string","title":"Type","description":"Stable event type, such as run.accepted, node.progress, or node.log."},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"nodeId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nodeid"},"progress":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Progress"},"data":{"additionalProperties":true,"type":"object","title":"Data"},"createdAt":{"type":"string","format":"date-time","title":"Createdat"}},"type":"object","required":["id","runId","type","createdAt"],"title":"PublicRunEvent"},"PublicRunFileInput":{"properties":{"type":{"type":"string","const":"file","title":"Type","description":"Input value is a REST API file reference."},"fileId":{"type":"string","title":"Fileid","description":"REST API file id returned by file upload completion."}},"type":"object","required":["type","fileId"],"title":"PublicRunFileInput"},"PublicRunFileInputReference":{"properties":{"nodeId":{"type":"string","title":"Nodeid"},"inputName":{"type":"string","title":"Inputname"},"fileId":{"type":"string","title":"Fileid"},"filename":{"type":"string","title":"Filename"},"contentType":{"type":"string","title":"Contenttype"},"sizeBytes":{"type":"integer","minimum":0.0,"title":"Sizebytes"},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalid"},"externalUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externaluserid"},"externalWorkspaceId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalworkspaceid"}},"type":"object","required":["nodeId","inputName","fileId","filename","contentType","sizeBytes"],"title":"PublicRunFileInputReference"},"PublicRunJsonInput":{"properties":{"type":{"type":"string","const":"json","title":"Type"},"value":{"title":"Value"}},"type":"object","required":["type","value"],"title":"PublicRunJsonInput"},"PublicRunNullInput":{"properties":{"type":{"type":"string","const":"null","title":"Type"},"value":{"type":"null","title":"Value"}},"type":"object","required":["type"],"title":"PublicRunNullInput"},"PublicRunNumberInput":{"properties":{"type":{"type":"string","const":"number","title":"Type"},"value":{"anyOf":[{"type":"number"},{"type":"integer"}],"title":"Value"}},"type":"object","required":["type","value"],"title":"PublicRunNumberInput"},"PublicRunSpendNode":{"properties":{"nodeId":{"type":"string","title":"Nodeid"},"nodeType":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nodetype"},"nodeTitle":{"type":"string","title":"Nodetitle"},"credits":{"type":"integer","minimum":0.0,"title":"Credits"},"microcredits":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Microcredits","description":"Exact billed amount in millionths of one credit."},"billedRuns":{"type":"integer","minimum":0.0,"title":"Billedruns","description":"Number of cost-bearing node execution snapshots counted for this node."}},"type":"object","required":["nodeId","nodeTitle","credits","billedRuns"],"title":"PublicRunSpendNode"},"PublicRunSpendSummary":{"properties":{"totalCredits":{"type":"integer","minimum":0.0,"title":"Totalcredits"},"totalMicrocredits":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Totalmicrocredits"},"byNode":{"items":{"$ref":"#/components/schemas/PublicRunSpendNode"},"type":"array","title":"Bynode"},"byProvider":{"additionalProperties":{"type":"integer"},"type":"object","title":"Byprovider"},"byProviderMicrocredits":{"additionalProperties":{"type":"string"},"type":"object","title":"Byprovidermicrocredits"},"byChargeType":{"additionalProperties":{"type":"integer"},"type":"object","title":"Bychargetype"},"byChargeTypeMicrocredits":{"additionalProperties":{"type":"string"},"type":"object","title":"Bychargetypemicrocredits"}},"type":"object","required":["totalCredits"],"title":"PublicRunSpendSummary"},"PublicRunStringInput":{"properties":{"type":{"type":"string","const":"string","title":"Type"},"value":{"type":"string","title":"Value"}},"type":"object","required":["type","value"],"title":"PublicRunStringInput"},"PublicStoryboardApplySummary":{"properties":{"sceneCount":{"type":"integer","minimum":0.0,"title":"Scenecount","description":"Number of sequences/scenes in the storyboard.","examples":[1]},"shotCount":{"type":"integer","minimum":0.0,"title":"Shotcount","description":"Number of shots/frames in the storyboard.","examples":[12]},"mediaCount":{"type":"integer","minimum":0.0,"title":"Mediacount","description":"Number of panel and audio media references.","examples":[12]},"mediaImported":{"type":"integer","minimum":0.0,"title":"Mediaimported","description":"Number of media references imported into internal storyboard frame slots.","examples":[10]},"mediaSkipped":{"type":"integer","minimum":0.0,"title":"Mediaskipped","description":"Number of media references skipped during apply.","examples":[1]},"unresolvedMedia":{"type":"integer","minimum":0.0,"title":"Unresolvedmedia","description":"Number of skipped unresolved media placeholders.","examples":[0]},"urlMedia":{"type":"integer","minimum":0.0,"title":"Urlmedia","description":"Number of skipped URL media references.","examples":[1]},"documentMedia":{"type":"integer","minimum":0.0,"title":"Documentmedia","description":"Number of skipped document media references.","examples":[0]},"extraPanelMedia":{"type":"integer","minimum":0.0,"title":"Extrapanelmedia","description":"Number of skipped extra panel media references.","examples":[0]},"warnings":{"items":{"$ref":"#/components/schemas/PublicStoryboardWarning"},"type":"array","title":"Warnings","description":"Non-fatal apply warnings."}},"type":"object","required":["sceneCount","shotCount","mediaCount","mediaImported","mediaSkipped","unresolvedMedia","urlMedia","documentMedia","extraPanelMedia"],"title":"PublicStoryboardApplySummary","example":{"documentMedia":0,"extraPanelMedia":0,"mediaCount":12,"mediaImported":12,"mediaSkipped":0,"sceneCount":1,"shotCount":12,"unresolvedMedia":0,"urlMedia":0,"warnings":[]}},"PublicStoryboardSummary":{"properties":{"sceneCount":{"type":"integer","minimum":0.0,"title":"Scenecount","description":"Number of sequences/scenes in the storyboard.","examples":[1]},"shotCount":{"type":"integer","minimum":0.0,"title":"Shotcount","description":"Number of shots/frames in the storyboard.","examples":[12]},"mediaCount":{"type":"integer","minimum":0.0,"title":"Mediacount","description":"Number of panel and audio media references.","examples":[12]}},"type":"object","required":["sceneCount","shotCount","mediaCount"],"title":"PublicStoryboardSummary","example":{"mediaCount":12,"sceneCount":1,"shotCount":12}},"PublicStoryboardToTimelineRequest":{"properties":{"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Kaitoi Storyboard Document v1 JSON to convert."},"name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Name","description":"Optional name for the generated Timeline Document."},"frameRate":{"type":"integer","title":"Framerate","description":"Timeline frame rate. Unsupported values normalize to 30.","default":30,"examples":[30]},"projectResolution":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Projectresolution","description":"Optional timeline project resolution."},"defaultDuration":{"anyOf":[{"type":"number","maximum":86400.0,"exclusiveMinimum":0.0},{"type":"null"}],"title":"Defaultduration","description":"Fallback shot duration in seconds when a storyboard shot omits durationSeconds."}},"type":"object","required":["document"],"title":"PublicStoryboardToTimelineRequest","example":{"defaultDuration":3,"document":{"kaitoiType":"storyboard","name":"Storyboard","sequences":[{"id":"scene-1","name":"Scene 1","order":0,"shots":[{"description":"A quiet establishing shot.","durationSeconds":3,"id":"frame-1","order":0,"transition":"cut"}]}],"settings":{"aspectRatio":"16:9","defaultFrameDuration":3},"version":1},"frameRate":30,"name":"Storyboard Timeline"}},"PublicStoryboardToTimelineResponse":{"properties":{"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Generated Kaitoi Timeline Document v1."},"summary":{"$ref":"#/components/schemas/PublicTimelineSummary","description":"Counts derived from the generated timeline document."},"warnings":{"items":{"$ref":"#/components/schemas/PublicStoryboardWarning"},"type":"array","title":"Warnings","description":"Non-fatal conversion warnings."}},"type":"object","required":["document","summary"],"title":"PublicStoryboardToTimelineResponse","example":{"document":{"kaitoiType":"timeline","name":"Timeline","timeline":{"clips":[{"duration":3,"filename":"hero.png","id":"clip-1","name":"Hero","opacity":100,"startTime":0,"storageType":"data","trackId":"track-1","transform":{"rotation":0,"scale":100,"x":0,"y":0},"trimEnd":0,"trimStart":0,"type":"image","volume":100}],"currentTime":0,"frameRate":30,"playheadPosition":0,"projectDuration":60,"projectResolution":{"height":1080,"isAutoDetected":true,"width":1920},"selectedClipIds":[],"selectedTrackId":"track-1","tracks":[{"height":60,"id":"track-1","locked":false,"mutedAudio":false,"mutedVideo":false,"name":"Track 1","volume":1}],"zoom":100},"version":1},"summary":{"clipCount":1,"durationSeconds":60,"trackCount":1},"warnings":[]}},"PublicStoryboardValidateRequest":{"properties":{"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Kaitoi Storyboard Document v1 JSON."}},"type":"object","required":["document"],"title":"PublicStoryboardValidateRequest","example":{"document":{"kaitoiType":"storyboard","name":"Storyboard","sequences":[{"id":"scene-1","name":"Scene 1","order":0,"shots":[{"description":"A quiet establishing shot.","durationSeconds":3,"id":"frame-1","order":0,"transition":"cut"}]}],"settings":{"aspectRatio":"16:9","defaultFrameDuration":3},"version":1}}},"PublicStoryboardValidationResponse":{"properties":{"valid":{"type":"boolean","title":"Valid","description":"Always true when the request succeeds."},"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Validated, normalized Kaitoi Storyboard Document v1."},"summary":{"$ref":"#/components/schemas/PublicStoryboardSummary","description":"Counts derived from the validated document."}},"type":"object","required":["valid","document","summary"],"title":"PublicStoryboardValidationResponse","example":{"document":{"kaitoiType":"storyboard","name":"Storyboard","sequences":[{"id":"scene-1","name":"Scene 1","order":0,"shots":[{"description":"A quiet establishing shot.","durationSeconds":3,"id":"frame-1","order":0,"transition":"cut"}]}],"settings":{"aspectRatio":"16:9","defaultFrameDuration":3},"version":1},"summary":{"mediaCount":0,"sceneCount":1,"shotCount":1},"valid":true}},"PublicStoryboardWarning":{"properties":{"code":{"type":"string","title":"Code","description":"Stable warning code.","examples":["URL_MEDIA_SKIPPED"]},"message":{"type":"string","title":"Message","description":"Human-readable warning message."},"path":{"type":"string","title":"Path","description":"Path to the affected storyboard document field.","examples":["document.sequences.0.shots.0.panels.1.media"]}},"type":"object","required":["code","message","path"],"title":"PublicStoryboardWarning","example":{"code":"URL_MEDIA_SKIPPED","message":"URL media references are not fetched or imported by the public API.","path":"document.sequences.0.shots.0.panels.0.media"}},"PublicTemplateDetail":{"properties":{"templateId":{"type":"string","title":"Templateid","description":"Stable template identifier.","examples":["template_123"]},"name":{"type":"string","title":"Name","description":"Template display name.","examples":["Portrait Generator"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Template description."},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"Template tags."},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","description":"Template category."},"source":{"type":"string","const":"user","title":"Source","description":"Template source exposed in this API slice.","default":"user"},"hasData":{"type":"boolean","title":"Hasdata","description":"Whether the template is backed by a bundled data template.","default":false},"nodeCount":{"type":"integer","title":"Nodecount","description":"Number of nodes in the template graph.","default":0},"createdAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Createdat","description":"Template creation timestamp."},"updatedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updatedat","description":"Template update timestamp."},"hasEndpoint":{"type":"boolean","title":"Hasendpoint","description":"True when this template has at least one active endpoint."},"endpoints":{"items":{"$ref":"#/components/schemas/PublicTemplateEndpointSummary"},"type":"array","title":"Endpoints","description":"Active endpoint summaries for this template."}},"type":"object","required":["templateId","name","hasEndpoint"],"title":"PublicTemplateDetail","example":{"category":"image","createdAt":"2026-06-01T12:00:00+00:00","description":"Creates a stylized portrait from a prompt.","endpoints":[],"hasData":false,"hasEndpoint":true,"name":"Portrait Generator","nodeCount":4,"source":"user","tags":["portrait"],"templateId":"template_123","updatedAt":"2026-06-02T12:00:00+00:00"}},"PublicTemplateEndpointAuthDocs":{"properties":{"scheme":{"type":"string","const":"bearer","title":"Scheme","description":"Authentication scheme.","default":"bearer"},"header":{"type":"string","const":"Authorization","title":"Header","description":"HTTP header name.","default":"Authorization"},"valueFormat":{"type":"string","title":"Valueformat","description":"Header value format for the external endpoint API key.","default":"Bearer <endpoint_api_key>"},"apiKeyReturnedOnce":{"type":"boolean","title":"Apikeyreturnedonce","description":"Endpoint API keys are shown only when created or regenerated.","default":true}},"type":"object","title":"PublicTemplateEndpointAuthDocs"},"PublicTemplateEndpointDocs":{"properties":{"templateId":{"type":"string","title":"Templateid","description":"Template identifier.","examples":["template_123"]},"endpointId":{"type":"string","title":"Endpointid","description":"Endpoint identifier.","examples":["endpoint_123"]},"name":{"type":"string","title":"Name","description":"Endpoint display name.","examples":["Generate Portrait"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Endpoint description."},"auth":{"$ref":"#/components/schemas/PublicTemplateEndpointAuthDocs","description":"Authentication requirements for the external endpoint."},"externalRun":{"$ref":"#/components/schemas/PublicTemplateEndpointRunDocs","description":"Current external endpoint run contract."},"ownerRun":{"$ref":"#/components/schemas/PublicTemplateEndpointOwnerRunDocs","description":"Owner-authenticated public API execution availability."},"inputs":{"items":{"$ref":"#/components/schemas/PublicTemplateEndpointPin"},"type":"array","title":"Inputs","description":"Exposed endpoint inputs."},"outputs":{"items":{"$ref":"#/components/schemas/PublicTemplateEndpointPin"},"type":"array","title":"Outputs","description":"Exposed endpoint outputs."},"requestExample":{"additionalProperties":true,"type":"object","title":"Requestexample","description":"Minimal JSON submit body example."}},"type":"object","required":["templateId","endpointId","name","externalRun","inputs","outputs","requestExample"],"title":"PublicTemplateEndpointDocs","example":{"auth":{"apiKeyReturnedOnce":true,"header":"Authorization","scheme":"bearer","valueFormat":"Bearer <endpoint_api_key>"},"description":"Creates a stylized portrait from a prompt.","endpointId":"endpoint_123","externalRun":{"contentTypes":["application/json","multipart/form-data"],"info":"/v1/run/endpoint_123/info","method":"POST","status":"/v1/run/endpoint_123/{task_id}","statusMethod":"GET","submit":"/v1/run/endpoint_123"},"inputs":[{"dataType":"string","fieldName":"prompt","kind":"primitive","name":"Prompt"}],"name":"Generate Portrait","outputs":[{"dataType":"image","fieldName":"image","kind":"file","name":"Image"}],"ownerRun":{"auth":"publicApiBearerToken","available":true,"contentTypes":["application/json"],"method":"POST","note":"Owner-authenticated execution uses the public API key owner and may spend credits.","status":"/api/v1/templates/template_123/endpoints/endpoint_123/runs/{taskId}","statusMethod":"GET","stream":"/api/v1/templates/template_123/endpoints/endpoint_123/runs/{taskId}/events/stream","streamMethod":"GET","submit":"/api/v1/templates/template_123/endpoints/endpoint_123/runs"},"requestExample":{"inputs":{"prompt":"A cinematic portrait"}},"templateId":"template_123"}},"PublicTemplateEndpointOwnerRunDocs":{"properties":{"available":{"type":"boolean","title":"Available","description":"Whether owner-authenticated public API execution is currently available for this template endpoint.","default":true},"submit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submit","description":"Owner-authenticated public API path for submitting an async template endpoint run."},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status","description":"Owner-authenticated public API path for polling a template endpoint run."},"stream":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stream","description":"Owner-authenticated public API path for streaming template endpoint run progress with Server-Sent Events."},"method":{"type":"string","const":"POST","title":"Method","description":"Submit method.","default":"POST"},"statusMethod":{"type":"string","const":"GET","title":"Statusmethod","description":"Status polling method.","default":"GET"},"streamMethod":{"type":"string","const":"GET","title":"Streammethod","description":"Progress stream method.","default":"GET"},"auth":{"type":"string","const":"publicApiBearerToken","title":"Auth","description":"Use a public API bearer token with templates:run scope.","default":"publicApiBearerToken"},"contentTypes":{"items":{"type":"string"},"type":"array","title":"Contenttypes","description":"Accepted owner-authenticated submit request content types."},"note":{"type":"string","title":"Note","description":"Current owner-authenticated execution status.","default":"Owner-authenticated execution uses the public API key owner and may spend credits."}},"type":"object","title":"PublicTemplateEndpointOwnerRunDocs"},"PublicTemplateEndpointPin":{"properties":{"name":{"type":"string","title":"Name","description":"Human-readable exposed input/output label.","examples":["Prompt"]},"fieldName":{"type":"string","title":"Fieldname","description":"Stable request/response field name.","examples":["prompt"]},"dataType":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Datatype","description":"Workflow data type for this exposed pin.","examples":["string"]},"kind":{"type":"string","enum":["primitive","text","file","unknown"],"title":"Kind","description":"Broad integration hint for whether this field expects scalar primitive, text-wrapper, or file-like data.","default":"unknown"},"nodeId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nodeid","description":"Template node id that owns the exposed pin."},"pinName":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pinname","description":"Node pin name inside the template graph."}},"type":"object","required":["name","fieldName"],"title":"PublicTemplateEndpointPin","example":{"dataType":"string","fieldName":"prompt","kind":"primitive","name":"Prompt","nodeId":"node_prompt","pinName":"text"}},"PublicTemplateEndpointRunDocs":{"properties":{"submit":{"type":"string","title":"Submit","description":"Path for submitting an async external template endpoint run."},"status":{"type":"string","title":"Status","description":"Path for polling a submitted external template endpoint run."},"info":{"type":"string","title":"Info","description":"Path for reading external endpoint metadata."},"method":{"type":"string","const":"POST","title":"Method","description":"Submit method.","default":"POST"},"statusMethod":{"type":"string","const":"GET","title":"Statusmethod","description":"Status polling method.","default":"GET"},"contentTypes":{"items":{"type":"string"},"type":"array","title":"Contenttypes","description":"Accepted submit request content types."}},"type":"object","required":["submit","status","info"],"title":"PublicTemplateEndpointRunDocs"},"PublicTemplateEndpointSummary":{"properties":{"endpointId":{"type":"string","title":"Endpointid","description":"Stable template endpoint identifier.","examples":["endpoint_123"]},"templateId":{"type":"string","title":"Templateid","description":"Template identifier this endpoint runs.","examples":["template_123"]},"name":{"type":"string","title":"Name","description":"Endpoint display name.","examples":["Generate Portrait"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Endpoint description."},"inputCount":{"type":"integer","title":"Inputcount","description":"Number of exposed inputs.","examples":[1]},"outputCount":{"type":"integer","title":"Outputcount","description":"Number of exposed outputs.","examples":[1]},"apiKeyPrefix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Apikeyprefix","description":"Non-secret prefix of the endpoint API key, useful for humans identifying the key.","examples":["wf_sk_abcd"]},"createdAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Createdat","description":"Endpoint creation timestamp."},"updatedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updatedat","description":"Endpoint update timestamp."},"lastCalled":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Lastcalled","description":"Most recent invocation timestamp, when available."},"callCount":{"type":"integer","title":"Callcount","description":"Number of recorded endpoint calls.","default":0,"examples":[12]},"isActive":{"type":"boolean","title":"Isactive","description":"Whether this endpoint currently accepts external calls.","default":true}},"type":"object","required":["endpointId","templateId","name","inputCount","outputCount"],"title":"PublicTemplateEndpointSummary","example":{"apiKeyPrefix":"wf_sk_abcd","callCount":0,"createdAt":"2026-06-01T12:00:00+00:00","description":"Creates a stylized portrait from a prompt.","endpointId":"endpoint_123","inputCount":1,"isActive":true,"name":"Generate Portrait","outputCount":1,"templateId":"template_123","updatedAt":"2026-06-01T12:00:00+00:00"}},"PublicTemplateRunCreateRequest":{"properties":{"inputs":{"additionalProperties":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/PublicRunFileInput"},{"$ref":"#/components/schemas/PublicRunStringInput"},{"$ref":"#/components/schemas/PublicRunNumberInput"},{"$ref":"#/components/schemas/PublicRunBooleanInput"},{"$ref":"#/components/schemas/PublicRunJsonInput"},{"$ref":"#/components/schemas/PublicRunNullInput"}],"discriminator":{"propertyName":"type","mapping":{"boolean":"#/components/schemas/PublicRunBooleanInput","file":"#/components/schemas/PublicRunFileInput","json":"#/components/schemas/PublicRunJsonInput","null":"#/components/schemas/PublicRunNullInput","number":"#/components/schemas/PublicRunNumberInput","string":"#/components/schemas/PublicRunStringInput"}}},{"type":"string"},{"type":"integer"},{"type":"number"},{"type":"boolean"},{"additionalProperties":true,"type":"object"},{"items":{},"type":"array"},{"type":"null"}]},"type":"object","title":"Inputs","description":"Input values keyed by exposed endpoint fieldName. File inputs should use {\"type\":\"file\",\"fileId\":\"...\"}; primitive values may use typed wrappers or direct JSON values."},"externalId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalid"},"externalUserId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externaluserid","description":"Developer end-user guard. Referenced files with externalUserId must match this value."},"externalWorkspaceId":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Externalworkspaceid"}},"type":"object","title":"PublicTemplateRunCreateRequest","example":{"externalUserId":"user_789","inputs":{"image":{"fileId":"2f8f8c5df80e4f76a5b7d1bbd6fae0ab.png","type":"file"},"prompt":{"type":"string","value":"A cinematic robot portrait"}}}},"PublicTemplateRunDetail":{"properties":{"taskId":{"type":"string","title":"Taskid","description":"Workflow task id used to poll this template endpoint run."},"sourceType":{"type":"string","const":"template_endpoint","title":"Sourcetype","default":"template_endpoint"},"templateId":{"type":"string","title":"Templateid"},"endpointId":{"type":"string","title":"Endpointid"},"status":{"type":"string","enum":["queued","running","succeeded","failed"],"title":"Status"},"progress":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Progress"},"progressMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Progressmessage"},"nodesCount":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Nodescount"},"nodeIndex":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Nodeindex"},"currentNode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currentnode"},"logs":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Logs"},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalid"},"externalUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externaluserid"},"externalWorkspaceId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalworkspaceid"},"inputFiles":{"items":{"$ref":"#/components/schemas/PublicRunFileInputReference"},"type":"array","title":"Inputfiles"},"outputs":{"additionalProperties":{"oneOf":[{"$ref":"#/components/schemas/PublicFileOutput"},{"$ref":"#/components/schemas/PublicPrimitiveOutput"}],"discriminator":{"propertyName":"type","mapping":{"boolean":"#/components/schemas/PublicPrimitiveOutput","file":"#/components/schemas/PublicFileOutput","json":"#/components/schemas/PublicPrimitiveOutput","null":"#/components/schemas/PublicPrimitiveOutput","number":"#/components/schemas/PublicPrimitiveOutput","string":"#/components/schemas/PublicPrimitiveOutput"}}},"type":"object","title":"Outputs"},"error":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Error"},"executionTimeMs":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Executiontimems"},"createdAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Createdat"},"updatedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updatedat"}},"type":"object","required":["taskId","templateId","endpointId","status"],"title":"PublicTemplateRunDetail"},"PublicTemplateSummary":{"properties":{"templateId":{"type":"string","title":"Templateid","description":"Stable template identifier.","examples":["template_123"]},"name":{"type":"string","title":"Name","description":"Template display name.","examples":["Portrait Generator"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Template description."},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","description":"Template tags."},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","description":"Template category."},"source":{"type":"string","const":"user","title":"Source","description":"Template source exposed in this API slice.","default":"user"},"hasData":{"type":"boolean","title":"Hasdata","description":"Whether the template is backed by a bundled data template.","default":false},"nodeCount":{"type":"integer","title":"Nodecount","description":"Number of nodes in the template graph.","default":0},"createdAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Createdat","description":"Template creation timestamp."},"updatedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updatedat","description":"Template update timestamp."},"hasEndpoint":{"type":"boolean","title":"Hasendpoint","description":"True when this template has at least one active endpoint."},"endpoints":{"items":{"$ref":"#/components/schemas/PublicTemplateEndpointSummary"},"type":"array","title":"Endpoints","description":"Active endpoint summaries for this template."}},"type":"object","required":["templateId","name","hasEndpoint"],"title":"PublicTemplateSummary","example":{"category":"image","createdAt":"2026-06-01T12:00:00+00:00","description":"Creates a stylized portrait from a prompt.","endpoints":[],"hasData":false,"hasEndpoint":true,"name":"Portrait Generator","nodeCount":4,"source":"user","tags":["portrait"],"templateId":"template_123","updatedAt":"2026-06-02T12:00:00+00:00"}},"PublicTimelineOtioExportRequest":{"properties":{"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Kaitoi Timeline Document v1 JSON to export as OpenTimelineIO."}},"type":"object","required":["document"],"title":"PublicTimelineOtioExportRequest","example":{"document":{"kaitoiType":"timeline","name":"Timeline","timeline":{"clips":[{"duration":3,"filename":"hero.png","id":"clip-1","name":"Hero","opacity":100,"startTime":0,"storageType":"data","trackId":"track-1","transform":{"rotation":0,"scale":100,"x":0,"y":0},"trimEnd":0,"trimStart":0,"type":"image","volume":100}],"currentTime":0,"frameRate":30,"playheadPosition":0,"projectDuration":60,"projectResolution":{"height":1080,"isAutoDetected":true,"width":1920},"selectedClipIds":[],"selectedTrackId":"track-1","tracks":[{"height":60,"id":"track-1","locked":false,"mutedAudio":false,"mutedVideo":false,"name":"Track 1","volume":1}],"zoom":100},"version":1}}},"PublicTimelineOtioImportResponse":{"properties":{"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Timeline Document produced from the OTIO input."},"summary":{"$ref":"#/components/schemas/PublicTimelineSummary","description":"Counts derived from the generated timeline document."},"warnings":{"items":{"$ref":"#/components/schemas/PublicTimelineWarning"},"type":"array","title":"Warnings","description":"Non-fatal import warnings."},"files":{"items":{"$ref":"#/components/schemas/PublicTimelineOtioImportedFile"},"type":"array","title":"Files","description":"Media files persisted by the import route. Empty for parse-only imports."}},"type":"object","required":["document","summary"],"title":"PublicTimelineOtioImportResponse","example":{"document":{"kaitoiType":"timeline","name":"Timeline","timeline":{"clips":[{"duration":3,"filename":"hero.png","id":"clip-1","name":"Hero","opacity":100,"startTime":0,"storageType":"data","trackId":"track-1","transform":{"rotation":0,"scale":100,"x":0,"y":0},"trimEnd":0,"trimStart":0,"type":"image","volume":100}],"currentTime":0,"frameRate":30,"playheadPosition":0,"projectDuration":60,"projectResolution":{"height":1080,"isAutoDetected":true,"width":1920},"selectedClipIds":[],"selectedTrackId":"track-1","tracks":[{"height":60,"id":"track-1","locked":false,"mutedAudio":false,"mutedVideo":false,"name":"Track 1","volume":1}],"zoom":100},"version":1},"files":[{"dataType":"video","filename":"hero.mp4","storagePath":"2f8f8c5df80e4f76a5b7d1bbd6fae0ab.mp4"}],"summary":{"clipCount":1,"durationSeconds":60,"trackCount":1},"warnings":[]}},"PublicTimelineOtioImportedFile":{"properties":{"filename":{"type":"string","title":"Filename","description":"Original media filename from the OTIO archive.","examples":["hero.mp4"]},"storagePath":{"type":"string","title":"Storagepath","description":"Library storage filename used by the returned timeline document.","examples":["2f8f8c5df80e4f76a5b7d1bbd6fae0ab.mp4"]},"dataType":{"type":"string","enum":["image","video","audio"],"title":"Datatype","description":"Detected media type."}},"type":"object","required":["filename","storagePath","dataType"],"title":"PublicTimelineOtioImportedFile","example":{"dataType":"video","filename":"hero.mp4","storagePath":"2f8f8c5df80e4f76a5b7d1bbd6fae0ab.mp4"}},"PublicTimelineSummary":{"properties":{"trackCount":{"type":"integer","minimum":0.0,"title":"Trackcount","description":"Number of tracks in the timeline.","examples":[1]},"clipCount":{"type":"integer","minimum":0.0,"title":"Clipcount","description":"Number of clips in the timeline.","examples":[12]},"durationSeconds":{"type":"number","minimum":0.0,"title":"Durationseconds","description":"Timeline project duration in seconds.","examples":[60]}},"type":"object","required":["trackCount","clipCount","durationSeconds"],"title":"PublicTimelineSummary","example":{"clipCount":12,"durationSeconds":60,"trackCount":1}},"PublicTimelineValidateRequest":{"properties":{"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Kaitoi Timeline Document v1 JSON."}},"type":"object","required":["document"],"title":"PublicTimelineValidateRequest","example":{"document":{"kaitoiType":"timeline","name":"Timeline","timeline":{"clips":[{"duration":3,"filename":"hero.png","id":"clip-1","name":"Hero","opacity":100,"startTime":0,"storageType":"data","trackId":"track-1","transform":{"rotation":0,"scale":100,"x":0,"y":0},"trimEnd":0,"trimStart":0,"type":"image","volume":100}],"currentTime":0,"frameRate":30,"playheadPosition":0,"projectDuration":60,"projectResolution":{"height":1080,"isAutoDetected":true,"width":1920},"selectedClipIds":[],"selectedTrackId":"track-1","tracks":[{"height":60,"id":"track-1","locked":false,"mutedAudio":false,"mutedVideo":false,"name":"Track 1","volume":1}],"zoom":100},"version":1}}},"PublicTimelineValidationResponse":{"properties":{"valid":{"type":"boolean","title":"Valid","description":"Always true when the request succeeds."},"document":{"additionalProperties":true,"type":"object","title":"Document","description":"Validated, normalized Kaitoi Timeline Document v1."},"summary":{"$ref":"#/components/schemas/PublicTimelineSummary","description":"Counts derived from the validated document."}},"type":"object","required":["valid","document","summary"],"title":"PublicTimelineValidationResponse","example":{"document":{"kaitoiType":"timeline","name":"Timeline","timeline":{"clips":[{"duration":3,"filename":"hero.png","id":"clip-1","name":"Hero","opacity":100,"startTime":0,"storageType":"data","trackId":"track-1","transform":{"rotation":0,"scale":100,"x":0,"y":0},"trimEnd":0,"trimStart":0,"type":"image","volume":100}],"currentTime":0,"frameRate":30,"playheadPosition":0,"projectDuration":60,"projectResolution":{"height":1080,"isAutoDetected":true,"width":1920},"selectedClipIds":[],"selectedTrackId":"track-1","tracks":[{"height":60,"id":"track-1","locked":false,"mutedAudio":false,"mutedVideo":false,"name":"Track 1","volume":1}],"zoom":100},"version":1},"summary":{"clipCount":1,"durationSeconds":60,"trackCount":1},"valid":true}},"PublicTimelineWarning":{"properties":{"code":{"type":"string","title":"Code","description":"Stable warning code.","examples":["MEDIA_FILE_MISSING"]},"message":{"type":"string","title":"Message","description":"Human-readable warning message."},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path","description":"Path or media reference associated with the warning."}},"type":"object","required":["code","message"],"title":"PublicTimelineWarning","example":{"code":"MEDIA_FILE_MISSING","message":"A referenced media file was not included in the OTIO upload.","path":"media.hero.mp4"}},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"importOtio":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_timelines.importOtio"},"parseOtio":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_timelines.parseOtio"},"upload":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"externalId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalid"},"externalUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externaluserid"},"externalWorkspaceId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalworkspaceid"}},"type":"object","required":["file"],"title":"Body_files.upload"}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"Programmatic Kaitoi API key."}}},"security":[{"BearerAuth":[]}]}