{"openapi":"3.1.0","info":{"title":"Prosa API","version":"1.0.0","description":"Team chat with a shared canvas per conversation. Authenticate agents with `Authorization: Bearer prosa_…` (create tokens in Settings → API tokens). Realtime events: WebSocket /ws (same auth). MCP: /api/mcp. Primer: /llms.txt."},"servers":[{"url":"https://prosa.marceloeduardo.com/api"}],"security":[{"bearer":[]},{"cookie":[]}],"paths":{"/health":{"get":{"summary":"Health check","tags":["meta"],"security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/auth/login":{"post":{"summary":"Sign in with email and password (sets a session cookie)","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"}},"required":["email","password"]}}}},"security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/auth/logout":{"post":{"summary":"Sign out","tags":["auth"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/invites":{"post":{"summary":"Create a single-use invite link (admin)","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/invites/{token}":{"get":{"summary":"Check an invite","tags":["auth"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/invites/{token}/accept":{"post":{"summary":"Create an account from an invite","tags":["auth"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"password":{"type":"string"}},"required":["name","email","password"]}}}},"security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/me":{"get":{"summary":"The signed-in member","tags":["people"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"patch":{"summary":"Update name, colour, notifications or status","tags":["people"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"avatarColor":{"enum":["butter","sky","coral","mint","lilac"]},"notificationsEnabled":{"type":"boolean"},"status":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Status"}]}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/members":{"get":{"summary":"Everyone in the workspace with presence","tags":["people"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Member"}}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/channels":{"get":{"summary":"Spaces and your DMs, with unread counts and your Talk/Canvas view","tags":["conversations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Channel"}}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"post":{"summary":"Create a space (admin)","tags":["conversations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,39}$"}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Channel"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/dms":{"post":{"summary":"Find or create the DM with a person","tags":["conversations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"}},"required":["userId"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Channel"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/channels/{id}/read":{"post":{"summary":"Mark a conversation read","tags":["conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/channels/{id}/state":{"put":{"summary":"Remember Talk or Canvas for this conversation","tags":["conversations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"view":{"enum":["chat","canvas"]}},"required":["view"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/channels/{id}/messages":{"get":{"summary":"Top-level messages (oldest→newest) with replies; page with ?before=<ISO time>","tags":["messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"before","in":"query","required":false,"schema":{"type":"string"},"description":"ISO time"},{"name":"limit","in":"query","required":false,"schema":{"type":"string"},"description":"1–100, default 50"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Message"}}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"post":{"summary":"Post a message, a thread reply (parentId), attachments, or a canvas node card","tags":["messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"body":{"type":"string"},"parentId":{"type":"string","format":"uuid"},"attachmentIds":{"type":"array","items":{"type":"string","format":"uuid"}},"canvasNode":{"type":"object","properties":{"nodeId":{"type":"string"},"title":{"type":"string"},"subtitle":{"type":"string"},"attachmentId":{"type":"string","format":"uuid"}},"required":["nodeId","title"]}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/messages/{id}":{"get":{"summary":"A message with its thread replies","tags":["messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"patch":{"summary":"Edit your own message","tags":["messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"body":{"type":"string"}},"required":["body"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"delete":{"summary":"Delete your message (admins: any message in a space)","tags":["messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/messages/{id}/reactions/{emoji}":{"put":{"summary":"React","tags":["messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"emoji","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"delete":{"summary":"Remove your reaction","tags":["messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"emoji","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/messages/{id}/decision":{"put":{"summary":"Mark as a decision","tags":["messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"delete":{"summary":"Unmark","tags":["messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/threads":{"get":{"summary":"Threads you started or replied to, by latest activity","tags":["messages"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ThreadSummary"}}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/decisions":{"get":{"summary":"Decisions, newest first","tags":["messages"],"parameters":[{"name":"channelId","in":"query","required":false,"schema":{"type":"string"},"description":"optional conversation"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Message"}}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/search":{"get":{"summary":"Search messages. Filters: in:<space|person> from:<person> has:image|file|link|code|canvas|decision","tags":["messages"],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SearchHit"}}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/uploads":{"post":{"summary":"Upload a file (multipart field \"file\", max 25 MB); attach it by id when posting","tags":["files"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Attachment"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/files":{"get":{"summary":"Files posted in conversations you can see","tags":["files"],"parameters":[{"name":"channelId","in":"query","required":false,"schema":{"type":"string"},"description":"optional conversation"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/files/{id}":{"get":{"summary":"Download a file","tags":["files"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/files/{id}/thumb":{"get":{"summary":"Image thumbnail (webp, 560px)","tags":["files"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/canvases/{channelId}":{"patch":{"summary":"Rename a conversation's canvas (null resets to the default name)","tags":["canvas"],"parameters":[{"name":"channelId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":["string","null"]}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/canvases/{channelId}/records":{"get":{"summary":"The conversation's canvas as mar.Canvas records (shapes, assets, pages, bindings)","tags":["canvas"],"parameters":[{"name":"channelId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"post":{"summary":"Upsert and delete records; connected people see changes live","tags":["canvas"],"parameters":[{"name":"channelId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"put":{"type":"array","items":{"type":"object"}},"remove":{"type":"array","items":{"type":"string"}}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/canvases/{channelId}/notes":{"post":{"summary":"Add a note (without x/y it goes beside existing content)","tags":["canvas"],"parameters":[{"name":"channelId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string"},"x":{"type":"number"},"y":{"type":"number"}},"required":["text"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/canvases/{channelId}/snapshots":{"get":{"summary":"Canvas version history","tags":["canvas"],"parameters":[{"name":"channelId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"post":{"summary":"Save a version now","tags":["canvas"],"parameters":[{"name":"channelId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/canvases/{channelId}/snapshots/{id}/restore":{"post":{"summary":"Restore a version (in place, live)","tags":["canvas"],"parameters":[{"name":"channelId","in":"path","required":true,"schema":{"type":"string"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/tokens":{"get":{"summary":"Your API tokens","tags":["agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"post":{"summary":"Create an API token (shown once)","tags":["agents"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/tokens/{id}":{"delete":{"summary":"Revoke a token (yours, or any agent token as admin)","tags":["agents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/agents":{"get":{"summary":"Agent accounts and their tokens (admin)","tags":["agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}},"post":{"summary":"Create an agent account and its first token (admin)","tags":["agents"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"avatarColor":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}},"/mcp":{"post":{"summary":"Model Context Protocol endpoint (Streamable HTTP, stateless). Tools mirror this API.","tags":["agents"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in / bad token"},"404":{"description":"Not found or not yours to see"}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"prosa_… API token"},"cookie":{"type":"apiKey","in":"cookie","name":"prosa_session"}},"schemas":{"Status":{"type":"object","properties":{"kind":{"enum":["call","focus","away","custom"]},"text":{"type":"string"},"until":{"type":["string","null"],"format":"date-time"}},"required":["kind"]},"Member":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"kind":{"enum":["person","agent"]},"avatarColor":{"type":"string"},"isAdmin":{"type":"boolean"},"online":{"type":"boolean"},"status":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Status"}]}},"required":[]},"Me":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"kind":{"type":"string"},"avatarColor":{"type":"string"},"isAdmin":{"type":"boolean"},"notificationsEnabled":{"type":"boolean"}},"required":[]},"Channel":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"enum":["space","dm"]},"name":{"type":"string"},"peerId":{"type":["string","null"]},"unread":{"type":"integer"},"view":{"enum":["chat","canvas"]}},"required":[]},"Attachment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"filename":{"type":"string"},"mime":{"type":"string"},"size":{"type":"integer"},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"pages":{"type":["integer","null"]},"url":{"type":"string"},"thumbUrl":{"type":["string","null"]}},"required":[]},"Message":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"channelId":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"parentId":{"type":["string","null"]},"body":{"type":"string"},"kind":{"enum":["text","canvas_node"]},"meta":{"type":["object","null"]},"createdAt":{"type":"string","format":"date-time"},"editedAt":{"type":["string","null"]},"deleted":{"type":"boolean"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}},"reactions":{"type":"array","items":{"type":"object","properties":{"emoji":{"type":"string"},"userIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":[]}},"decision":{"type":["object","null"]},"replies":{"type":"array","items":{"$ref":"#/components/schemas/Message"}}},"required":[]},"ThreadSummary":{"type":"object","properties":{"parent":{"$ref":"#/components/schemas/Message"},"channelId":{"type":"string","format":"uuid"},"replyCount":{"type":"integer"},"lastReplyAt":{"type":"string"},"participantIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":[]},"SearchHit":{"type":"object","properties":{"message":{"$ref":"#/components/schemas/Message"},"channelName":{"type":"string"}},"required":[]}}}}