{"openapi":"3.0.3","info":{"title":"Trident Public REST API","version":"1.0.0","description":"\nThe **Trident Public REST API** enables developers and automated agents to interact with Trident diagrams programmatically.\n\n### Key Capabilities\n- **File Management**: CRUD operations on diagram files with automatic server-side AES-256-GCM envelope encryption.\n- **Federated Live Session Conflict Detection**: Returns `409 FILE_IN_USE` if a diagram is being actively edited in a collaborative session on Cloudflare Durable Objects.\n- **Collaboration Tokens**: Mint scoped access tokens (`tri_collab_...`) for AI assistants (MCP) or automated tools.\n- **Collaborator Management**: Add, list, update roles, and remove human collaborators or pending email invitations, with tier-based quota enforcement.\n\n### Authentication\nAuthenticate requests using the **App Token** generated in the **My Account** section of Trident ([https://tridentchart.com/account.html](https://tridentchart.com/account.html)).\nPass the token in the HTTP `Authorization` header:\n```http\nAuthorization: Bearer tri_app_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n```\n","contact":{"name":"Trident API Support","url":"https://tridentchart.com/contact.html"},"license":{"name":"Proprietary","url":"https://tridentchart.com/terms.html"}},"servers":[{"url":"/api/v1","description":"Production API (relative ingress)"},{"url":"https://tridentchart.com/api/v1","description":"Production API (direct HTTPS)"}],"security":[{"BearerAuth":[]}],"paths":{"/health":{"get":{"tags":["System"],"summary":"API Health Check","description":"Verifies the operational status of the Trident Public API. Does not require authentication.","security":[],"responses":{"200":{"description":"API is healthy and operational","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/openapi.json":{"get":{"tags":["System"],"summary":"OpenAPI Specification","description":"Returns the machine-readable OpenAPI 3.0 specification in JSON format. Does not require authentication.","security":[],"responses":{"200":{"description":"OpenAPI JSON specification","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/files":{"get":{"tags":["Files"],"summary":"List Files","description":"Returns a list of diagram files owned by the authenticated user.","parameters":[{"name":"limit","in":"query","description":"Maximum number of files to return (1-200, default 50)","required":false,"schema":{"type":"integer","default":50,"minimum":1,"maximum":200}},{"name":"starred","in":"query","description":"Filter by starred status (true or false)","required":false,"schema":{"type":"boolean"}},{"name":"folderId","in":"query","description":"Filter files by parent folder ID","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of diagrams","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Files"],"summary":"Create File","description":"Creates a new Trident diagram. Content is encrypted at rest using envelope encryption. Validates user subscription tier limits.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFileRequest"}}}},"responses":{"201":{"description":"File successfully created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDetail"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenTierLimit"}}}},"/files/{fileId}":{"parameters":[{"name":"fileId","in":"path","required":true,"description":"The unique ID of the diagram file","schema":{"type":"string"}}],"get":{"tags":["Files"],"summary":"Get File Details","description":"Retrieves diagram metadata and decrypted DSL content. If the file is currently open in an active live session, returns 409 Conflict.","responses":{"200":{"description":"File details and decrypted DSL content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDetail"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/FileInUse"}}},"patch":{"tags":["Files"],"summary":"Update File","description":"Updates diagram metadata (name, starred status, folder) and/or DSL content. Re-encrypts content on change. Returns 409 Conflict if in an active live session.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFileRequest"}}}},"responses":{"200":{"description":"Updated file details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDetail"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/FileInUse"}}},"delete":{"tags":["Files"],"summary":"Delete File","description":"Deletes a diagram file (soft-delete by default, or permanent deletion if `permanent=true`). Returns 409 Conflict if in an active live session.","parameters":[{"name":"permanent","in":"query","description":"Set to true for permanent deletion; otherwise soft-deletes the file","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"File successfully deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"id":{"type":"string","example":"doc_123"},"deleted":{"type":"boolean","example":true},"permanent":{"type":"boolean","example":false}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/FileInUse"}}}},"/files/{fileId}/collaboration-tokens":{"parameters":[{"name":"fileId","in":"path","required":true,"description":"The unique ID of the diagram file","schema":{"type":"string"}}],"post":{"tags":["Collaboration Tokens"],"summary":"Mint Collaboration Token","description":"Generates a scoped collaboration token (`tri_collab_...`) for an AI assistant (MCP) or external automation. Sets `aiShared: true` on the document.","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollabTokenRequest"}}}},"responses":{"201":{"description":"Collaboration token minted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollabTokenResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenCollabQuota"},"404":{"$ref":"#/components/responses/NotFound"}}},"get":{"tags":["Collaboration Tokens"],"summary":"List Collaboration Tokens","description":"Lists all active, non-revoked collaboration tokens for the specified file.","responses":{"200":{"description":"List of active collaboration tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollabTokenListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/files/{fileId}/collaboration-tokens/{tokenId}":{"parameters":[{"name":"fileId","in":"path","required":true,"description":"The unique ID of the diagram file","schema":{"type":"string"}},{"name":"tokenId","in":"path","required":true,"description":"The token hash ID to revoke","schema":{"type":"string"}}],"delete":{"tags":["Collaboration Tokens"],"summary":"Revoke Collaboration Token","description":"Revokes a collaboration token. If no active tokens remain on the file, the document `aiShared` flag is automatically cleared.","responses":{"200":{"description":"Token successfully revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeTokenResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/files/{fileId}/collaborators":{"parameters":[{"name":"fileId","in":"path","required":true,"description":"The unique ID of the diagram file","schema":{"type":"string"}}],"get":{"tags":["Collaborators"],"summary":"List Collaborators & Invites","description":"Returns active human collaborators, pending email invitations, and document owner metadata.","responses":{"200":{"description":"Collaborators and pending invites list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollaboratorListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"tags":["Collaborators"],"summary":"Add or Invite Collaborator","description":"Adds a collaborator by email or userId. If the user already has a Trident account, grants immediate access. If not registered, stores a pending invite and sends an invitation email. Enforces tier limits (Free: 1 share, Pro: 10 shares).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCollaboratorRequest"}}}},"responses":{"201":{"description":"Collaborator added or invite created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollaboratorItem"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenCollabQuota"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"User is already an active collaborator","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"User is already a collaborator on this file","code":"ALREADY_EXISTS"}}}}}}},"/files/{fileId}/collaborators/{collaboratorId}":{"parameters":[{"name":"fileId","in":"path","required":true,"description":"The unique ID of the diagram file","schema":{"type":"string"}},{"name":"collaboratorId","in":"path","required":true,"description":"The collaborator identifier: user UID, email address, or pending invite ID","schema":{"type":"string"}}],"patch":{"tags":["Collaborators"],"summary":"Update Collaborator Role","description":"Updates a collaborator or pending invite role (editor or viewer). Supports collaboratorId as a user UID, email address, or invite ID.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCollaboratorRoleRequest"}}}},"responses":{"200":{"description":"Role updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollaboratorItem"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Collaborators"],"summary":"Remove Collaborator / Rescind Invite","description":"Removes an active collaborator from the file or rescinds a pending invitation. Supports collaboratorId as a user UID, email address, or invite ID.","responses":{"200":{"description":"Collaborator removed or invite rescinded","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"id":{"type":"string","example":"usr_abc123"},"type":{"type":"string","enum":["user","invite"],"example":"user"},"removed":{"type":"boolean","example":true},"rescinded":{"type":"boolean","example":true}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}}},"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"tri_app_...","description":"App Token generated in your Trident Account settings (https://tridentchart.com/account.html)."}},"schemas":{"HealthResponse":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"service":{"type":"string","example":"trident-public-api"},"version":{"type":"string","example":"1.0.0"}},"required":["status","service","version"]},"FileSummary":{"type":"object","properties":{"id":{"type":"string","example":"f8d3a1b4-1234-5678-9abc-def012345678"},"name":{"type":"string","example":"System Architecture"},"createdAt":{"type":"string","format":"date-time","example":"2026-09-07T12:00:00.000Z"},"lastModified":{"type":"string","format":"date-time","example":"2026-09-07T14:30:00.000Z"},"starred":{"type":"boolean","example":false},"folderId":{"type":"string","nullable":true,"example":null},"size":{"type":"integer","example":1024},"role":{"type":"string","enum":["owner","editor","viewer"],"example":"owner"}},"required":["id","name","createdAt","lastModified"]},"FileListResponse":{"type":"object","properties":{"files":{"type":"array","items":{"$ref":"#/components/schemas/FileSummary"}},"count":{"type":"integer","example":1}},"required":["files"]},"FileDetail":{"type":"object","properties":{"id":{"type":"string","example":"f8d3a1b4-1234-5678-9abc-def012345678"},"name":{"type":"string","example":"System Architecture"},"content":{"type":"string","example":"node A \"Web App\"\nnode B \"API Gateway\"\nA -> B"},"createdAt":{"type":"string","format":"date-time","example":"2026-09-07T12:00:00.000Z"},"lastModified":{"type":"string","format":"date-time","example":"2026-09-07T14:30:00.000Z"},"starred":{"type":"boolean","example":false},"folderId":{"type":"string","nullable":true,"example":null},"size":{"type":"integer","example":54},"role":{"type":"string","enum":["owner","editor","viewer"],"example":"owner"}},"required":["id","name","content"]},"CreateFileRequest":{"type":"object","properties":{"name":{"type":"string","description":"Name of the diagram","example":"Microservices Flow"},"content":{"type":"string","description":"Trident DSL source code","example":"node S1 \"Auth Service\"\nnode S2 \"Database\"\nS1 -> S2"},"folderId":{"type":"string","nullable":true,"description":"Parent folder ID","example":null}},"required":["name"]},"UpdateFileRequest":{"type":"object","properties":{"name":{"type":"string","description":"Updated name of the diagram","example":"Revised Architecture"},"content":{"type":"string","description":"Updated Trident DSL source code","example":"node S1 \"Service A\"\nnode S2 \"Service B\"\nS1 -> S2"},"starred":{"type":"boolean","description":"Starred flag for quick access","example":true},"folderId":{"type":"string","nullable":true,"description":"Target parent folder ID","example":"folder_xyz"}}},"CreateCollabTokenRequest":{"type":"object","properties":{"role":{"type":"string","enum":["editor","viewer"],"default":"editor","description":"Permissions granted by the collaboration token"},"scope":{"type":"string","enum":["ai","api"],"default":"ai","description":"Target audience: AI assistant (MCP) or API integration"},"name":{"type":"string","description":"Human-readable label for tracking","example":"Claude Desktop MCP"},"expiresInMs":{"type":"integer","nullable":true,"description":"Token lifetime in milliseconds (null for non-expiring)","example":86400000}}},"CollabTokenResponse":{"type":"object","properties":{"tokenId":{"type":"string","example":"a9f0e8..."},"token":{"type":"string","example":"tri_collab_ZmlsZTEyMw.randombytes..."},"fileId":{"type":"string","example":"f8d3a1b4-1234..."},"role":{"type":"string","enum":["editor","viewer"],"example":"editor"},"scope":{"type":"string","enum":["ai","api"],"example":"ai"},"name":{"type":"string","example":"Claude Desktop MCP"},"expiresAt":{"type":"string","format":"date-time","nullable":true},"workerUrl":{"type":"string","example":"https://trident-collab-worker.abespalov.workers.dev"}},"required":["tokenId","token","fileId","role","scope","workerUrl"]},"CollabTokenSummary":{"type":"object","properties":{"tokenId":{"type":"string","example":"a9f0e8..."},"name":{"type":"string","example":"Claude Desktop MCP"},"role":{"type":"string","enum":["editor","viewer"],"example":"editor"},"scope":{"type":"string","enum":["ai","api"],"example":"ai"},"expiresAt":{"type":"string","format":"date-time","nullable":true},"lastUsedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}},"required":["tokenId","role","scope"]},"CollabTokenListResponse":{"type":"object","properties":{"fileId":{"type":"string","example":"f8d3a1b4-1234..."},"tokens":{"type":"array","items":{"$ref":"#/components/schemas/CollabTokenSummary"}},"count":{"type":"integer","example":1}},"required":["fileId","tokens","count"]},"RevokeTokenResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"tokenId":{"type":"string","example":"a9f0e8..."},"revoked":{"type":"boolean","example":true}},"required":["success","tokenId","revoked"]},"AddCollaboratorRequest":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Email address of user to add or invite","example":"collaborator@example.com"},"userId":{"type":"string","description":"Firebase Auth UID of registered user","example":"usr_xyz123"},"role":{"type":"string","enum":["editor","viewer"],"default":"editor","description":"Access role granted to collaborator"}}},"CollaboratorItem":{"type":"object","properties":{"id":{"type":"string","example":"usr_xyz123"},"type":{"type":"string","enum":["user","invite"],"example":"user"},"userId":{"type":"string","nullable":true,"example":"usr_xyz123"},"email":{"type":"string","format":"email","nullable":true,"example":"collaborator@example.com"},"displayName":{"type":"string","nullable":true,"example":"Jane Doe"},"photoUrl":{"type":"string","nullable":true,"example":null},"role":{"type":"string","enum":["editor","viewer"],"example":"editor"},"status":{"type":"string","enum":["active","pending"],"example":"active"},"grantedBy":{"type":"string","nullable":true,"example":"owner_uid"},"invitedBy":{"type":"string","nullable":true,"example":"owner_uid"},"invitedAt":{"type":"string","format":"date-time","nullable":true}},"required":["id","type","role","status"]},"CollaboratorListResponse":{"type":"object","properties":{"fileId":{"type":"string","example":"f8d3a1b4-1234..."},"owner":{"type":"object","properties":{"userId":{"type":"string","example":"owner_uid"},"email":{"type":"string","nullable":true,"example":"owner@example.com"},"displayName":{"type":"string","nullable":true,"example":"Alexei Bespalov"}},"required":["userId"]},"collaborators":{"type":"array","items":{"$ref":"#/components/schemas/CollaboratorItem"}},"count":{"type":"integer","example":2}},"required":["fileId","owner","collaborators","count"]},"UpdateCollaboratorRoleRequest":{"type":"object","properties":{"role":{"type":"string","enum":["editor","viewer"],"description":"New role for collaborator or invite","example":"viewer"}},"required":["role"]},"ApiError":{"type":"object","properties":{"error":{"type":"string","example":"Resource not found"},"code":{"type":"string","example":"NOT_FOUND"}},"required":["error","code"]}},"responses":{"BadRequest":{"description":"Invalid input parameters or request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Invalid argument provided","code":"INVALID_ARGUMENT"}}}},"Unauthorized":{"description":"Missing, invalid, or revoked App Token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Invalid or missing App Token. Format: Authorization: Bearer tri_app_...","code":"UNAUTHORIZED"}}}},"Forbidden":{"description":"Insufficient permissions for this resource","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Only the owner or an editor can perform this action","code":"FORBIDDEN"}}}},"ForbiddenTierLimit":{"description":"Subscription plan quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Free tier is limited to 5 diagrams. Upgrade to Pro for unlimited diagrams.","code":"TIER_LIMIT_EXCEEDED"}}}},"ForbiddenCollabQuota":{"description":"Collaboration limit exceeded for subscription tier","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"You can share each document with up to 1 collaborator (human + AI) on your plan. Upgrade to Pro to share with up to 10.","code":"COLLAB_LIMIT_EXCEEDED"}}}},"NotFound":{"description":"File or resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"File not found","code":"NOT_FOUND"}}}},"FileInUse":{"description":"Diagram is currently open in an active live collaborative editing session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"File is currently in use in an active editing session. Please close the session or try again shortly.","code":"FILE_IN_USE"}}}}}}}