{"openapi":"3.1.0","info":{"title":"UserJot Public API","version":"1.0.0","description":"Public REST API for managing UserJot workspace resources. POST /conversations/{conversation_id}/replies, POST /conversations/{conversation_id}/notes, POST /requests, POST /changelogs, and POST /assets/import support the optional Idempotency-Key header; other mutation routes do not use explicit request-key replay semantics. Core resource-creation routes return the created resource, while relationship/addition routes return acknowledgement payloads such as { ok: true }."},"security":[{"bearerAuth":[]}],"tags":[{"name":"Boards","description":"Manage feedback boards."},{"name":"Requests","description":"Create, read, update, and delete requests."},{"name":"Request Workflow","description":"Update request status and move between boards."},{"name":"Request Comments","description":"Manage comments on requests."},{"name":"Request Comment Votes","description":"Manage votes on request comments."},{"name":"Request Comment Attachments","description":"Manage attachments on request comments."},{"name":"Request Votes","description":"Manage votes on requests."},{"name":"Request Subscriptions","description":"Manage request subscriptions."},{"name":"Request Attachments","description":"Manage attachments on requests."},{"name":"Request Tags","description":"Manage request tag definitions and assignments."},{"name":"Changelogs","description":"Create, read, update, and delete changelog entries."},{"name":"Changelog Authors","description":"Manage changelog entry authors."},{"name":"Changelog Requests","description":"Manage requests linked to changelog entries."},{"name":"Changelog Tags","description":"Manage changelog tag definitions and assignments."},{"name":"Members","description":"Manage members and erase personal data while retaining authored content."},{"name":"Companies","description":"Manage companies."},{"name":"Company Members","description":"Manage company-member relationships."},{"name":"Assets","description":"Upload and read public image assets."},{"name":"Conversations","description":"Read and triage workspace conversations."}],"servers":[{"url":"https://api.userjot.com/v1","description":"Production API"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token","description":"Use a UserJot API token in the Authorization header as `Bearer <token>`."}},"schemas":{"BoardListResponse":{"type":"object","properties":{"boards":{"type":"array","items":{"$ref":"#/components/schemas/Board"}}},"required":["boards"],"description":"Board list response."},"Board":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"name":{"type":"string"},"slug":{"type":"string"},"color":{"$ref":"#/components/schemas/BoardColor"},"type":{"$ref":"#/components/schemas/BoardType"},"order":{"type":"integer"}},"required":["id","name","slug","color","type","order"],"description":"Board resource."},"PublicId":{"type":"string","minLength":1,"description":"Opaque UserJot resource identifier."},"BoardColor":{"type":"string","enum":["gray","gold","bronze","brown","yellow","amber","orange","tomato","red","ruby","crimson","pink","plum","purple","violet","iris","indigo","blue","cyan","teal","jade","green","grass","lime","mint","sky"],"description":"Public board color value."},"BoardType":{"type":"string","enum":["public","private"],"description":"Public board type."},"InvalidApiTokenErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_api_token"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for invalid_api_token."},"InternalErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["internal_error"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for internal_error."},"BoardResponse":{"type":"object","properties":{"board":{"$ref":"#/components/schemas/Board"}},"required":["board"],"description":"Single-board response."},"BoardNameConflictErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["board_name_conflict"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for board_name_conflict."},"PlanLimitReachedErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["plan_limit_reached"]},"message":{"type":"string"},"details":{"$ref":"#/components/schemas/PlanLimitReachedDetails"}},"required":["code","message","details"]}},"required":["error"],"description":"Public API error response for plan_limit_reached."},"PlanLimitReachedDetails":{"type":"object","properties":{"resource":{"type":"string","enum":["feedback_board","feedback_tag","changelog_tag"]},"limit":{"type":"integer","minimum":0},"usage":{"type":"integer","minimum":0}},"required":["resource","limit","usage"],"description":"Structured details returned when a plan quota is exhausted."},"ValidationErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["validation_error"]},"message":{"type":"string"},"details":{"type":"object","properties":{"issues":{"type":"array","items":{"$ref":"#/components/schemas/ValidationIssue"}}},"required":["issues"]}},"required":["code","message","details"]}},"required":["error"],"description":"Validation error response."},"ValidationIssue":{"type":"object","properties":{"path":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"}},"required":["path","code","message"],"description":"Validation issue details for a failed request."},"CreateBoardRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"color":{"$ref":"#/components/schemas/BoardColor"}},"required":["name","color"],"additionalProperties":false,"description":"Create-board request body."},"NotFoundErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["not_found"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for not_found."},"PlanFeatureUnavailableErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["plan_feature_unavailable"]},"message":{"type":"string"},"details":{"$ref":"#/components/schemas/PlanFeatureUnavailableDetails"}},"required":["code","message","details"]}},"required":["error"],"description":"Public API error response for plan_feature_unavailable."},"PlanFeatureUnavailableDetails":{"type":"object","properties":{"feature":{"type":"string","enum":["private_boards","api_access"]}},"required":["feature"],"description":"Structured details returned when the current plan lacks a feature."},"UpdateBoardRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"color":{"$ref":"#/components/schemas/BoardColor"},"type":{"$ref":"#/components/schemas/BoardType"}},"additionalProperties":false,"description":"Update-board request body.","minProperties":1},"BoardNotEmptyErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["board_not_empty"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for board_not_empty."},"RequestTagListResponse":{"type":"object","properties":{"tags":{"type":"array","items":{"$ref":"#/components/schemas/RequestTag"}}},"required":["tags"],"description":"Request-tag list response."},"RequestTag":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"name":{"type":"string"}},"required":["id","name"],"description":"Request tag resource."},"RequestTagResponse":{"type":"object","properties":{"tag":{"$ref":"#/components/schemas/RequestTag"}},"required":["tag"],"description":"Single request-tag response."},"TagNameConflictErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["tag_name_conflict"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for tag_name_conflict."},"CreateRequestTagRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64}},"required":["name"],"additionalProperties":false,"description":"Create-request-tag request body."},"RequestListResponse":{"type":"object","properties":{"requests":{"type":"array","items":{"$ref":"#/components/schemas/Request"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["requests","next_cursor"],"description":"Request-list response."},"Request":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"title":{"type":"string"},"body":{"type":"string"},"status":{"$ref":"#/components/schemas/RequestStatus"},"board":{"$ref":"#/components/schemas/RequestBoard"},"author":{"$ref":"#/components/schemas/Member"},"tags":{"type":"array","items":{"$ref":"#/components/schemas/RequestTag"}},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"},"status_updated_at":{"$ref":"#/components/schemas/Timestamp"},"vote_count":{"type":"integer","minimum":0},"comment_count":{"type":"integer","minimum":0}},"required":["id","title","body","status","board","author","tags","attachments","created_at","updated_at","status_updated_at","vote_count","comment_count"],"description":"Public request resource."},"RequestStatus":{"type":"string","enum":["pending","review","planned","in_progress","completed","closed"],"description":"Public request workflow status."},"RequestBoard":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"name":{"type":"string"},"slug":{"type":"string"},"color":{"$ref":"#/components/schemas/BoardColor"},"type":{"$ref":"#/components/schemas/BoardType"}},"required":["id","name","slug","color","type"],"description":"Board summary embedded in a request resource. Omits order because board ordering is only relevant on board-listing surfaces."},"Member":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"external_id":{"type":["string","null"],"minLength":1},"type":{"$ref":"#/components/schemas/MemberType"},"email":{"type":["string","null"],"format":"email"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"avatar_url":{"$ref":"#/components/schemas/NullableHttpsUrl"},"traits":{"$ref":"#/components/schemas/MemberTraits"},"created_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["id","external_id","type","email","first_name","last_name","avatar_url","traits","created_at"],"description":"Public member resource."},"MemberType":{"type":"string","enum":["user","admin","owner","guest","anonymous"],"description":"Public member type."},"NullableHttpsUrl":{"anyOf":[{"$ref":"#/components/schemas/HttpsUrl"},{"type":"null"}],"description":"HTTPS URL or null."},"HttpsUrl":{"type":"string","format":"uri","description":"HTTPS URL.","pattern":"^https://.+"},"MemberTraits":{"type":"object","properties":{"monthlySpend":{"type":["number","null"],"minimum":0},"plan":{"type":["string","null"]},"isTrialing":{"type":["boolean","null"]}},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]},"description":"Public member traits object. Known trait keys intentionally use camelCase to stay consistent with the UserJot widget and identify APIs."},"Timestamp":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$","description":"ISO 8601 UTC timestamp with millisecond precision."},"Attachment":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"url":{"$ref":"#/components/schemas/HttpsUrl"}},"required":["id","url"],"description":"Attachment resource."},"NullableCursor":{"anyOf":[{"$ref":"#/components/schemas/Cursor"},{"type":"null"}],"description":"Opaque pagination cursor or null."},"Cursor":{"type":"string","minLength":1,"description":"Opaque pagination cursor."},"MemberErasedErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["member_erased"]},"message":{"type":"string"},"details":{"type":"object","properties":{"erased_at":{"type":"string","format":"date-time"}}}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for member_erased."},"RequestSort":{"type":"string","enum":["newest","oldest","top","status_updated"],"description":"Request list sort order. newest and oldest order by creation time. top orders by vote count, highest first. status_updated orders by the most recent status change first; combine with statuses to list recently closed or completed requests."},"RequestResponse":{"type":"object","properties":{"request":{"$ref":"#/components/schemas/Request"}},"required":["request"],"description":"Single-request response."},"IdempotencyKeyReusedErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["idempotency_key_reused"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for idempotency_key_reused."},"IdempotencyInProgressErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["idempotency_in_progress"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for idempotency_in_progress."},"InvalidAttachmentErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_attachment"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for invalid_attachment."},"CreateRequestRequest":{"type":"object","properties":{"author":{"$ref":"#/components/schemas/MemberRef"},"board_id":{"$ref":"#/components/schemas/PublicId"},"title":{"type":"string","minLength":1,"maxLength":255},"body":{"type":"string","minLength":1,"maxLength":20000},"tag_ids":{"type":"array","items":{"$ref":"#/components/schemas/PublicId"}},"attachment_urls":{"type":"array","items":{"$ref":"#/components/schemas/HttpsUrl"},"minItems":1,"maxItems":4},"status":{"$ref":"#/components/schemas/RequestStatus"}},"required":["author","board_id","title","body"],"additionalProperties":false,"description":"Create-request request body."},"MemberRef":{"anyOf":[{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"external_id":{"type":"string","minLength":1}},"required":["external_id"],"additionalProperties":false}],"description":"Reference to an existing member by id or customer external_id. Exactly one of id or external_id must be provided."},"UpdateRequestRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"body":{"type":"string","minLength":1,"maxLength":20000}},"additionalProperties":false,"description":"Update-request request body.","minProperties":1},"SimilarRequestsResponse":{"type":"object","properties":{"requests":{"type":"array","items":{"$ref":"#/components/schemas/SimilarRequest"}}},"required":["requests"],"description":"Similar-requests response."},"SimilarRequest":{"allOf":[{"$ref":"#/components/schemas/Request"},{"type":"object","properties":{"similarity":{"type":"number","minimum":0,"maximum":1,"description":"Cosine similarity to the source request, from 0 to 1, rounded to 4 decimals."}},"required":["similarity"]}],"description":"Request with its similarity score to the source request."},"OkResponse":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"],"description":"Simple success acknowledgement response."},"UpdateRequestStatusRequest":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/RequestStatus"},"actor":{"$ref":"#/components/schemas/MemberRef"}},"required":["status"],"additionalProperties":false,"description":"Request-status update request body."},"MoveRequestBoardRequest":{"type":"object","properties":{"board_id":{"$ref":"#/components/schemas/PublicId"},"actor":{"$ref":"#/components/schemas/MemberRef"}},"required":["board_id"],"additionalProperties":false,"description":"Request-board move request body."},"RequestAttachmentsResponse":{"type":"object","properties":{"attachments":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}}},"required":["attachments"],"description":"Request-attachments response."},"AddRequestAttachmentsRequest":{"type":"object","properties":{"attachment_urls":{"type":"array","items":{"$ref":"#/components/schemas/HttpsUrl"},"minItems":1,"maxItems":4}},"required":["attachment_urls"],"additionalProperties":false,"description":"Add-request-attachments request body."},"RequestCommentsResponse":{"type":"object","properties":{"comments":{"type":"array","items":{"$ref":"#/components/schemas/RequestCommentThread"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["comments","next_cursor"],"description":"Request-comments response."},"RequestCommentThread":{"allOf":[{"$ref":"#/components/schemas/Comment"},{"type":"object","properties":{"replies":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}}},"required":["replies"]}],"description":"Top-level comment with inline replies."},"NullablePublicId":{"anyOf":[{"$ref":"#/components/schemas/PublicId"},{"type":"null"}],"description":"Opaque UserJot resource identifier or null."},"CommentVisibility":{"type":"string","enum":["public","internal"],"description":"Public comment visibility."},"Comment":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"body":{"type":"string"},"parent_id":{"$ref":"#/components/schemas/NullablePublicId"},"visibility":{"$ref":"#/components/schemas/CommentVisibility"},"pinned":{"type":"boolean"},"author":{"$ref":"#/components/schemas/Member"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"},"vote_count":{"type":"integer","minimum":0}},"required":["id","body","parent_id","visibility","pinned","author","attachments","created_at","updated_at","vote_count"],"description":"Public comment resource."},"CommentResponse":{"type":"object","properties":{"comment":{"$ref":"#/components/schemas/Comment"}},"required":["comment"],"description":"Single-comment response."},"InvalidParentCommentErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_parent_comment"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for invalid_parent_comment."},"CreateRequestCommentRequest":{"type":"object","properties":{"author":{"$ref":"#/components/schemas/MemberRef"},"body":{"type":"string","minLength":1,"maxLength":10000},"parent_id":{"$ref":"#/components/schemas/PublicId"},"attachment_urls":{"type":"array","items":{"$ref":"#/components/schemas/HttpsUrl"},"minItems":1,"maxItems":4},"visibility":{"$ref":"#/components/schemas/CommentVisibility"}},"required":["author","body"],"additionalProperties":false,"description":"Create-request-comment request body."},"UpdateCommentRequest":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":10000}},"additionalProperties":false,"description":"Update-comment request body.","minProperties":1},"CommentAttachmentsResponse":{"type":"object","properties":{"attachments":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}}},"required":["attachments"],"description":"Comment-attachments response."},"AddCommentAttachmentsRequest":{"type":"object","properties":{"attachment_urls":{"type":"array","items":{"$ref":"#/components/schemas/HttpsUrl"},"minItems":1,"maxItems":4}},"required":["attachment_urls"],"additionalProperties":false,"description":"Add-comment-attachments request body."},"CommentVotesResponse":{"type":"object","properties":{"votes":{"type":"array","items":{"$ref":"#/components/schemas/CommentVote"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["votes","next_cursor"],"description":"Comment-votes response."},"CommentVote":{"type":"object","properties":{"voter":{"$ref":"#/components/schemas/Member"},"created_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["voter","created_at"],"description":"Vote on a comment."},"AddCommentVoteRequest":{"type":"object","properties":{"voter":{"$ref":"#/components/schemas/MemberRef"}},"required":["voter"],"additionalProperties":false,"description":"Add-comment-vote request body."},"InvalidRequestErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for invalid_request."},"RequestVotesResponse":{"type":"object","properties":{"votes":{"type":"array","items":{"$ref":"#/components/schemas/RequestVote"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["votes","next_cursor"],"description":"Request-votes response."},"RequestVote":{"type":"object","properties":{"voter":{"$ref":"#/components/schemas/Member"},"created_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["voter","created_at"],"description":"Vote on a request."},"AddRequestVoteRequest":{"type":"object","properties":{"voter":{"$ref":"#/components/schemas/MemberRef"}},"required":["voter"],"additionalProperties":false,"description":"Add-request-vote request body."},"RequestSubscriptionsResponse":{"type":"object","properties":{"subscriptions":{"type":"array","items":{"$ref":"#/components/schemas/RequestSubscription"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["subscriptions","next_cursor"],"description":"Request-subscriptions response."},"RequestSubscription":{"type":"object","properties":{"subscriber":{"$ref":"#/components/schemas/Member"},"created_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["subscriber","created_at"],"description":"Subscription to a request."},"AddRequestSubscriptionRequest":{"type":"object","properties":{"subscriber":{"$ref":"#/components/schemas/MemberRef"}},"required":["subscriber"],"additionalProperties":false,"description":"Add-request-subscription request body."},"RequestTagsResponse":{"type":"object","properties":{"tags":{"type":"array","items":{"$ref":"#/components/schemas/RequestTag"}}},"required":["tags"],"description":"Request-tags response."},"AddRequestTagsRequest":{"type":"object","properties":{"tag_ids":{"type":"array","items":{"$ref":"#/components/schemas/PublicId"},"minItems":1}},"required":["tag_ids"],"additionalProperties":false,"description":"Add-request-tags request body."},"ChangelogTagListResponse":{"type":"object","properties":{"tags":{"type":"array","items":{"$ref":"#/components/schemas/ChangelogTag"}}},"required":["tags"],"description":"Changelog-tag list response."},"ChangelogTag":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"name":{"type":"string"}},"required":["id","name"],"description":"Changelog tag resource."},"ChangelogTagResponse":{"type":"object","properties":{"tag":{"$ref":"#/components/schemas/ChangelogTag"}},"required":["tag"],"description":"Single changelog-tag response."},"CreateChangelogTagRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64}},"required":["name"],"additionalProperties":false,"description":"Create-changelog-tag request body."},"ChangelogListResponse":{"type":"object","properties":{"changelogs":{"type":"array","items":{"$ref":"#/components/schemas/ChangelogListItem"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["changelogs","next_cursor"],"description":"Changelog-list response."},"ChangelogListItem":{"allOf":[{"$ref":"#/components/schemas/Changelog"},{"type":"object","properties":{"tags":{"type":"array","items":{"$ref":"#/components/schemas/ChangelogTag"}},"authors":{"type":"array","items":{"$ref":"#/components/schemas/Member"}}},"required":["tags","authors"]}],"description":"Changelog list item."},"Asset":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"url":{"$ref":"#/components/schemas/HttpsUrl"},"name":{"type":"string"},"content_type":{"type":"string","description":"MIME type. Currently one of image/png, image/jpeg, image/gif, image/webp."},"size_bytes":{"type":"integer","exclusiveMinimum":0},"kind":{"type":"string","description":"Asset kind. Currently always \"image\". New kinds may be added; treat unknown values as opaque."},"image":{"$ref":"#/components/schemas/AssetImage"},"created_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["id","url","name","content_type","size_bytes","kind","image","created_at"],"description":"Public asset resource."},"AssetImage":{"type":["object","null"],"properties":{"width":{"type":["integer","null"],"exclusiveMinimum":0},"height":{"type":["integer","null"],"exclusiveMinimum":0}},"required":["width","height"],"description":"Present when kind is \"image\"."},"ChangelogStatus":{"type":"string","enum":["draft","published"],"description":"Persisted changelog status."},"Changelog":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"title":{"type":"string"},"markdown":{"type":"string","description":"Entry body as markdown. A video embed is a link to its YouTube embed URL on its own line, for example [YouTube video](https://www.youtube.com/embed/dQw4w9WgXcQ). In create and update, a YouTube video URL alone on a line becomes an embed."},"html":{"type":"string","description":"Rendered HTML of the entry body. A video embed is a div with the data-youtube-video attribute wrapping an iframe whose src is a YouTube embed URL."},"short":{"type":["string","null"]},"cover":{"anyOf":[{"$ref":"#/components/schemas/Asset"},{"type":"null"}],"description":"Cover image asset, or null when the entry has no cover managed as an asset."},"status":{"$ref":"#/components/schemas/ChangelogStatus"},"publish_at":{"$ref":"#/components/schemas/Timestamp"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["id","title","markdown","html","short","cover","status","publish_at","created_at","updated_at"],"description":"Public changelog resource. publish_at is always present in responses because changelog ordering and scheduling semantics are based on the stored publish timestamp."},"ChangelogStatusFilter":{"type":"string","enum":["draft","published","scheduled"],"description":"List filter for changelog status, including virtual scheduled. The scheduled filter matches entries whose persisted status is published and whose publish_at is still in the future."},"ChangelogResponse":{"type":"object","properties":{"changelog":{"$ref":"#/components/schemas/Changelog"}},"required":["changelog"],"description":"Single changelog response."},"InvalidChangelogAuthorErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_changelog_author"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for invalid_changelog_author."},"CreateChangelogRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"markdown":{"type":"string","minLength":1,"maxLength":100000},"short":{"anyOf":[{"type":"string","minLength":1,"maxLength":500},{"type":"null"}],"description":"Optional changelog summary. Use null to clear it; empty strings are rejected."},"cover_asset_id":{"$ref":"#/components/schemas/PublicId"},"status":{"$ref":"#/components/schemas/ChangelogStatus"},"publish_at":{"$ref":"#/components/schemas/Timestamp"},"authors":{"type":"array","items":{"$ref":"#/components/schemas/MemberRef"},"maxItems":100},"tag_ids":{"type":"array","items":{"$ref":"#/components/schemas/PublicId"},"maxItems":100},"request_ids":{"type":"array","items":{"$ref":"#/components/schemas/PublicId"},"maxItems":100}},"required":["title","markdown"],"additionalProperties":false,"description":"Create-changelog request body. short must be a non-empty string when provided; omit it to leave it null."},"ChangelogDetailResponse":{"type":"object","properties":{"changelog":{"$ref":"#/components/schemas/ChangelogDetail"}},"required":["changelog"],"description":"Detailed changelog response."},"ChangelogDetail":{"allOf":[{"$ref":"#/components/schemas/Changelog"},{"type":"object","properties":{"tags":{"type":"array","items":{"$ref":"#/components/schemas/ChangelogTag"}},"authors":{"type":"array","items":{"$ref":"#/components/schemas/Member"}},"requests":{"type":"array","items":{"$ref":"#/components/schemas/Request"}}},"required":["tags","authors","requests"]}],"description":"Detailed changelog resource."},"UpdateChangelogRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":255},"markdown":{"type":"string","minLength":1,"maxLength":100000},"short":{"anyOf":[{"type":"string","minLength":1,"maxLength":500},{"type":"null"}],"description":"Optional changelog summary. Use null to clear it; empty strings are rejected."},"cover_asset_id":{"$ref":"#/components/schemas/NullablePublicId"},"status":{"$ref":"#/components/schemas/ChangelogStatus"},"publish_at":{"$ref":"#/components/schemas/Timestamp"}},"additionalProperties":false,"description":"Update-changelog request body. short must be a non-empty string when provided; use null to clear it.","minProperties":1},"ChangelogTagsResponse":{"type":"object","properties":{"tags":{"type":"array","items":{"$ref":"#/components/schemas/ChangelogTag"}}},"required":["tags"],"description":"Changelog-tags response."},"AddChangelogTagsRequest":{"type":"object","properties":{"tag_ids":{"type":"array","items":{"$ref":"#/components/schemas/PublicId"},"minItems":1}},"required":["tag_ids"],"additionalProperties":false,"description":"Add-changelog-tags request body."},"ChangelogAuthorsResponse":{"type":"object","properties":{"authors":{"type":"array","items":{"$ref":"#/components/schemas/Member"}}},"required":["authors"],"description":"Changelog-authors response."},"AddChangelogAuthorsRequest":{"type":"object","properties":{"authors":{"type":"array","items":{"$ref":"#/components/schemas/MemberRef"},"minItems":1}},"required":["authors"],"additionalProperties":false,"description":"Add-changelog-authors request body."},"ChangelogRequestsResponse":{"type":"object","properties":{"requests":{"type":"array","items":{"$ref":"#/components/schemas/Request"}}},"required":["requests"],"description":"Changelog-requests response."},"AddChangelogRequestsRequest":{"type":"object","properties":{"request_ids":{"type":"array","items":{"$ref":"#/components/schemas/PublicId"},"minItems":1}},"required":["request_ids"],"additionalProperties":false,"description":"Add-changelog-requests request body."},"AssetResponse":{"type":"object","properties":{"asset":{"$ref":"#/components/schemas/Asset"}},"required":["asset"]},"InvalidAssetErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_asset"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for invalid_asset."},"CreateAssetForm":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"name":{"type":"string","minLength":1,"maxLength":255}},"required":["file"]},"ImportAssetRequest":{"type":"object","properties":{"url":{"$ref":"#/components/schemas/HttpsUrl"},"name":{"type":"string","minLength":1,"maxLength":255}},"required":["url"],"additionalProperties":false},"MemberNotErasableErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["member_not_erasable"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for member_not_erasable."},"MemberResponse":{"type":"object","properties":{"member":{"$ref":"#/components/schemas/Member"}},"required":["member"],"description":"Single-member response."},"MemberIdentityConflictErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["member_identity_conflict"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for member_identity_conflict."},"MemberEmailConflictErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["member_email_conflict"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for member_email_conflict."},"SyncMemberRequest":{"type":"object","properties":{"external_id":{"type":"string","minLength":1},"email":{"type":["string","null"],"format":"email"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"avatar_url":{"$ref":"#/components/schemas/NullableHttpsUrl"},"traits":{"$ref":"#/components/schemas/MemberTraits"},"companies":{"type":"array","items":{"$ref":"#/components/schemas/InlineMemberCompany"}}},"required":["external_id"],"additionalProperties":false,"description":"Create-or-update member request body. Inline companies may be synced for convenience; each inline company still requires name when it is being created for the first time."},"InlineMemberCompany":{"type":"object","properties":{"external_id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"domain":{"type":["string","null"]},"logo_url":{"$ref":"#/components/schemas/NullableHttpsUrl"},"traits":{"$ref":"#/components/schemas/CompanyTraits"}},"required":["external_id"],"additionalProperties":false,"description":"Inline company sync payload inside member sync. name is required when the referenced company is being created for the first time."},"CompanyTraits":{"type":"object","properties":{"monthlySpend":{"type":["number","null"],"minimum":0},"plan":{"type":["string","null"]},"industry":{"type":["string","null"]},"companySize":{"type":["number","null"]}},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]},"description":"Public company traits object. Known trait keys intentionally use camelCase to stay consistent with the UserJot widget and identify APIs."},"MembersListResponse":{"type":"object","properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/Member"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["members","next_cursor"],"description":"Member-list response."},"ListableMemberType":{"type":"string","enum":["user","admin","owner"],"description":"Public member type returned by listable member endpoints."},"UpdateMemberRequest":{"type":"object","properties":{"external_id":{"type":"string","minLength":1},"email":{"type":["string","null"],"format":"email"},"first_name":{"type":["string","null"]},"last_name":{"type":["string","null"]},"avatar_url":{"$ref":"#/components/schemas/NullableHttpsUrl"},"traits":{"$ref":"#/components/schemas/MemberTraits"}},"additionalProperties":false,"description":"Update-member request body.","minProperties":1},"ConversationListResponse":{"type":"object","properties":{"conversations":{"type":"array","items":{"$ref":"#/components/schemas/Conversation"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["conversations","next_cursor"],"description":"Conversation-list response."},"Conversation":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"status":{"$ref":"#/components/schemas/ConversationStatus"},"inbox_state":{"anyOf":[{"$ref":"#/components/schemas/ConversationInboxState"},{"type":"null"}],"description":"Triage state. null once a conversation is no longer open."},"source":{"type":"string","description":"Channel that opened the conversation. Currently \"widget\" or \"email\". New sources may be added; treat unknown values as opaque."},"subject":{"type":["string","null"]},"preview":{"type":["string","null"],"description":"Short plain-text excerpt of the latest customer-visible message."},"participants":{"type":"array","items":{"$ref":"#/components/schemas/Actor"},"minItems":1,"description":"People in the conversation, in the order they joined. Every participant is currently a customer. When an anonymous visitor is later identified as a member, the member replaces the visitor here and earlier timeline entries keep their original actor."},"assignee":{"anyOf":[{"$ref":"#/components/schemas/Actor"},{"type":"null"}]},"snoozed_until":{"anyOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"resolved_at":{"anyOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"last_customer_message_at":{"anyOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]},"last_reply_at":{"anyOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}],"description":"Last public reply from a team member or Juno."},"created_at":{"$ref":"#/components/schemas/Timestamp"},"updated_at":{"allOf":[{"$ref":"#/components/schemas/Timestamp"},{"description":"Moves on every new entry and state change, including internal ones such as notes and assignments. Edits to existing messages may not move it. Use with updated_since to poll."}]}},"required":["id","status","inbox_state","source","subject","preview","participants","assignee","snoozed_until","resolved_at","last_customer_message_at","last_reply_at","created_at","updated_at"],"description":"Conversation resource."},"ConversationStatus":{"type":"string","enum":["open","resolved","archived","spam"]},"ConversationInboxState":{"type":"string","enum":["needs_team","ai_handling","waiting_on_customer"]},"Actor":{"type":"object","properties":{"id":{"allOf":[{"$ref":"#/components/schemas/PublicId"},{"description":"Stable identity handle within the workspace. Two conversations from the same identified member or the same email sender share it; two anonymous visitors never do."}]},"type":{"$ref":"#/components/schemas/ActorType"},"name":{"type":"string","minLength":1,"description":"Display name. Never null; falls back to an email address, a visitor pseudonym, \"Juno\", \"System\", or \"Anonymous\"."},"email":{"type":["string","null"],"format":"email","description":"When member is null this address is self-reported by the visitor or taken from the email header and is not verified."},"avatar_url":{"$ref":"#/components/schemas/NullableHttpsUrl"},"member":{"anyOf":[{"$ref":"#/components/schemas/Member"},{"type":"null"}]}},"required":["id","type","name","email","avatar_url","member"],"description":"Person or agent on a conversation, with the full member when one exists."},"ActorType":{"type":"string","enum":["customer","team","ai","system"],"description":"Role the actor plays in the conversation. customer: a person the workspace is helping. team: a workspace owner or admin acting for the workspace. ai: Juno. system: automation."},"ConversationResponse":{"type":"object","properties":{"conversation":{"$ref":"#/components/schemas/Conversation"}},"required":["conversation"],"description":"Single-conversation response."},"ConversationTimelineResponse":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/TimelineEntry"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["entries","next_cursor"]},"TimelineEntry":{"oneOf":[{"$ref":"#/components/schemas/MessageEntry"},{"$ref":"#/components/schemas/NoteEntry"},{"$ref":"#/components/schemas/AiHandoffEntry"},{"$ref":"#/components/schemas/ResolvedEntry"},{"$ref":"#/components/schemas/ReopenedEntry"},{"$ref":"#/components/schemas/AssignedEntry"},{"$ref":"#/components/schemas/UnassignedEntry"}],"discriminator":{"propertyName":"type","mapping":{"message":"#/components/schemas/MessageEntry","note":"#/components/schemas/NoteEntry","ai_handoff":"#/components/schemas/AiHandoffEntry","resolved":"#/components/schemas/ResolvedEntry","reopened":"#/components/schemas/ReopenedEntry","assigned":"#/components/schemas/AssignedEntry","unassigned":"#/components/schemas/UnassignedEntry"}},"description":"One entry in a conversation timeline. New types may be added; treat unknown values as opaque and render body when present."},"MessageEntry":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"conversation_id":{"$ref":"#/components/schemas/PublicId"},"visibility":{"type":"string","enum":["public","internal"],"description":"public entries are visible to the customer."},"actor":{"$ref":"#/components/schemas/TimelineActor"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"type":{"type":"string","enum":["message"]},"body":{"type":"string","description":"Message content as Markdown. Only bold, italic, strikethrough, inline code, links, bullet and numbered lists, blockquotes, and code blocks appear; there are no headings, images, or tables."},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/ConversationAttachment"}},"edited_at":{"anyOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]}},"required":["id","conversation_id","visibility","actor","created_at","type","body","attachments","edited_at"],"description":"A message in the thread. actor.type says whether a customer, a team member, Juno, or automation wrote it."},"TimelineActor":{"type":"object","properties":{"id":{"allOf":[{"$ref":"#/components/schemas/PublicId"},{"description":"Stable identity handle within the workspace. Two conversations from the same identified member or the same email sender share it; two anonymous visitors never do."}]},"type":{"$ref":"#/components/schemas/ActorType"},"name":{"type":"string","minLength":1,"description":"Display name. Never null; falls back to an email address, a visitor pseudonym, \"Juno\", \"System\", or \"Anonymous\"."},"email":{"type":["string","null"],"format":"email","description":"When member is null this address is self-reported by the visitor or taken from the email header and is not verified."},"avatar_url":{"$ref":"#/components/schemas/NullableHttpsUrl"},"member":{"anyOf":[{"$ref":"#/components/schemas/MemberSummary"},{"type":"null"}]}},"required":["id","type","name","email","avatar_url","member"],"description":"Person or agent on a timeline entry, with a member summary when one exists."},"MemberSummary":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"external_id":{"type":["string","null"],"minLength":1},"type":{"$ref":"#/components/schemas/MemberType"}},"required":["id","external_id","type"],"description":"Member reference embedded on timeline entries. Fetch the member for traits."},"ConversationAttachment":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"name":{"type":"string"},"content_type":{"type":"string"},"size_bytes":{"type":"integer","minimum":0},"url":{"allOf":[{"$ref":"#/components/schemas/HttpsUrl"},{"description":"Signed download URL. Expires at url_expires_at; re-fetch the entry for a fresh one."}]},"url_expires_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["id","name","content_type","size_bytes","url","url_expires_at"]},"NoteEntry":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"conversation_id":{"$ref":"#/components/schemas/PublicId"},"visibility":{"type":"string","enum":["public","internal"],"description":"public entries are visible to the customer."},"actor":{"$ref":"#/components/schemas/TimelineActor"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"type":{"type":"string","enum":["note"]},"body":{"type":"string","description":"Message content as Markdown. Only bold, italic, strikethrough, inline code, links, bullet and numbered lists, blockquotes, and code blocks appear; there are no headings, images, or tables."},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/ConversationAttachment"}},"edited_at":{"anyOf":[{"$ref":"#/components/schemas/Timestamp"},{"type":"null"}]}},"required":["id","conversation_id","visibility","actor","created_at","type","body","attachments","edited_at"]},"AiHandoffEntry":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"conversation_id":{"$ref":"#/components/schemas/PublicId"},"visibility":{"type":"string","enum":["public","internal"],"description":"public entries are visible to the customer."},"actor":{"$ref":"#/components/schemas/TimelineActor"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"type":{"type":"string","enum":["ai_handoff"]},"handoff_reason":{"type":"string","enum":["user_requested_human","low_confidence","knowledge_gap","safety_or_policy","tool_error","channel_unsupported","team_takeover"]},"handoff_trigger":{"type":"string","enum":["customer_message","customer_button","ai_decision","system_policy","team_action"]}},"required":["id","conversation_id","visibility","actor","created_at","type","handoff_reason","handoff_trigger"]},"ResolvedEntry":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"conversation_id":{"$ref":"#/components/schemas/PublicId"},"visibility":{"type":"string","enum":["public","internal"],"description":"public entries are visible to the customer."},"actor":{"$ref":"#/components/schemas/TimelineActor"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"type":{"type":"string","enum":["resolved"]},"resolution_reason":{"type":"string","enum":["manual","ai_inactivity"]}},"required":["id","conversation_id","visibility","actor","created_at","type","resolution_reason"]},"ReopenedEntry":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"conversation_id":{"$ref":"#/components/schemas/PublicId"},"visibility":{"type":"string","enum":["public","internal"],"description":"public entries are visible to the customer."},"actor":{"$ref":"#/components/schemas/TimelineActor"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"type":{"type":"string","enum":["reopened"]},"previous_status":{"type":"string","enum":["resolved","archived"]}},"required":["id","conversation_id","visibility","actor","created_at","type","previous_status"]},"AssignedEntry":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"conversation_id":{"$ref":"#/components/schemas/PublicId"},"visibility":{"type":"string","enum":["public","internal"],"description":"public entries are visible to the customer."},"actor":{"$ref":"#/components/schemas/TimelineActor"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"type":{"type":"string","enum":["assigned"]},"assignee":{"$ref":"#/components/schemas/TimelineActor"},"previous_assignee":{"anyOf":[{"$ref":"#/components/schemas/TimelineActor"},{"type":"null"}]}},"required":["id","conversation_id","visibility","actor","created_at","type","assignee","previous_assignee"]},"UnassignedEntry":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"conversation_id":{"$ref":"#/components/schemas/PublicId"},"visibility":{"type":"string","enum":["public","internal"],"description":"public entries are visible to the customer."},"actor":{"$ref":"#/components/schemas/TimelineActor"},"created_at":{"$ref":"#/components/schemas/Timestamp"},"type":{"type":"string","enum":["unassigned"]},"previous_assignee":{"$ref":"#/components/schemas/TimelineActor"}},"required":["id","conversation_id","visibility","actor","created_at","type","previous_assignee"]},"TimelineEntryType":{"type":"string","enum":["message","note","ai_handoff","resolved","reopened","assigned","unassigned"]},"ConversationEntryResponse":{"type":"object","properties":{"entry":{"$ref":"#/components/schemas/TimelineEntry"}},"required":["entry"]},"ConversationStatusConflictErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["conversation_status_conflict"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for conversation_status_conflict."},"InvalidConversationActorErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_conversation_actor"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for invalid_conversation_actor."},"CreateConversationReplyRequest":{"type":"object","properties":{"actor":{"$ref":"#/components/schemas/MemberRef"},"body":{"type":"string","minLength":1,"description":"Message content as Markdown. Bold, italic, strikethrough, inline code, links, bullet and numbered lists, blockquotes, and code blocks are kept. Headings and images are flattened to their text; tables and HTML are kept as literal text."}},"required":["actor","body"],"additionalProperties":false},"CreateConversationNoteRequest":{"type":"object","properties":{"actor":{"$ref":"#/components/schemas/MemberRef"},"body":{"type":"string","minLength":1,"description":"Message content as Markdown. Bold, italic, strikethrough, inline code, links, bullet and numbered lists, blockquotes, and code blocks are kept. Headings and images are flattened to their text; tables and HTML are kept as literal text."}},"required":["actor","body"],"additionalProperties":false},"UpdateConversationStatusRequest":{"type":"object","properties":{"status":{"type":"string","enum":["open","resolved"]},"actor":{"$ref":"#/components/schemas/MemberRef"}},"required":["status","actor"],"additionalProperties":false},"InvalidConversationAssigneeErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_conversation_assignee"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for invalid_conversation_assignee."},"UpdateConversationAssigneeRequest":{"type":"object","properties":{"assignee":{"anyOf":[{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"}},"required":["id"],"additionalProperties":false},{"type":"object","properties":{"external_id":{"type":"string","minLength":1}},"required":["external_id"],"additionalProperties":false},{"type":"null"}]},"actor":{"$ref":"#/components/schemas/MemberRef"}},"required":["assignee","actor"],"additionalProperties":false},"CompanyResponse":{"type":"object","properties":{"company":{"$ref":"#/components/schemas/Company"}},"required":["company"],"description":"Single-company response."},"Company":{"type":"object","properties":{"id":{"$ref":"#/components/schemas/PublicId"},"external_id":{"type":["string","null"],"minLength":1},"name":{"type":"string"},"domain":{"type":["string","null"]},"logo_url":{"$ref":"#/components/schemas/NullableHttpsUrl"},"traits":{"$ref":"#/components/schemas/CompanyTraits"},"created_at":{"$ref":"#/components/schemas/Timestamp"}},"required":["id","external_id","name","domain","logo_url","traits","created_at"],"description":"Public company resource."},"CompanyIdentityConflictErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["company_identity_conflict"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"description":"Public API error response for company_identity_conflict."},"SyncCompanyRequest":{"type":"object","properties":{"external_id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"domain":{"type":["string","null"]},"logo_url":{"$ref":"#/components/schemas/NullableHttpsUrl"},"traits":{"$ref":"#/components/schemas/CompanyTraits"}},"required":["external_id"],"additionalProperties":false,"description":"Create-or-update company request body. name is required when the referenced company is being created for the first time."},"CompaniesListResponse":{"type":"object","properties":{"companies":{"type":"array","items":{"$ref":"#/components/schemas/Company"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["companies","next_cursor"],"description":"Company-list response."},"UpdateCompanyRequest":{"type":"object","properties":{"external_id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"domain":{"type":["string","null"]},"logo_url":{"$ref":"#/components/schemas/NullableHttpsUrl"},"traits":{"$ref":"#/components/schemas/CompanyTraits"}},"additionalProperties":false,"description":"Update-company request body.","minProperties":1},"CompanyMembersResponse":{"type":"object","properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/Member"}},"next_cursor":{"$ref":"#/components/schemas/NullableCursor"}},"required":["members","next_cursor"],"description":"Company-members response."},"AddCompanyMemberRequest":{"type":"object","properties":{"member":{"$ref":"#/components/schemas/MemberRef"}},"required":["member"],"additionalProperties":false,"description":"Add-company-member request body."},"RateLimitedErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["rate_limited"]},"message":{"type":"string"},"details":{"type":"object","properties":{"retry_after_seconds":{"type":"integer","minimum":1}},"required":["retry_after_seconds"]}},"required":["code","message","details"]}},"required":["error"],"description":"Rate-limited error response."}}},"paths":{"/boards":{"get":{"operationId":"listBoards","tags":["Boards"],"summary":"List boards","description":"Lists boards for the organization resolved from the bearer token. Returns all boards; this collection is not paginated in v1.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Boards returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardListResponse"},"example":{"boards":[{"id":"brd_001","name":"Ideas","slug":"ideas","color":"indigo","type":"public","order":1},{"id":"brd_002","name":"Bugs","slug":"bugs","color":"violet","type":"private","order":2}]}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"createBoard","tags":["Boards"],"summary":"Create board","description":"Creates a board, generates its slug automatically, requires the board name to be unique within the organization, defaults the board type to public, and returns plan_limit_reached when the current board quota is exhausted.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBoardRequest"},"example":{"name":"Bugs","color":"gray"}}}},"responses":{"201":{"description":"Board created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"},"example":{"board":{"id":"brd_003","name":"Bugs","slug":"bugs","color":"gray","type":"public","order":3}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Board name already exists or the organization has already reached its board quota.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/BoardNameConflictErrorResponse"},{"$ref":"#/components/schemas/PlanLimitReachedErrorResponse"}]},"examples":{"board_name_conflict":{"value":{"error":{"code":"board_name_conflict","message":"Board name already exists"}}},"plan_limit_reached":{"value":{"error":{"code":"plan_limit_reached","message":"Plan limit reached","details":{"resource":"feedback_board","limit":2,"usage":2}}}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"name","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/boards/{board_id}":{"get":{"operationId":"getBoard","tags":["Boards"],"summary":"Get board","description":"Retrieves a single board by internal id.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"brd_001"},"required":true,"name":"board_id","in":"path"}],"responses":{"200":{"description":"Board returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"},"example":{"board":{"id":"brd_001","name":"Ideas","slug":"ideas","color":"indigo","type":"public","order":1}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Board not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"patch":{"operationId":"updateBoard","tags":["Boards"],"summary":"Update board","description":"Updates board fields by internal id. Board names must remain unique within the organization. If the name changes, the slug is regenerated. Changing type from public to private requires a plan that supports private boards.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"brd_001"},"required":true,"name":"board_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBoardRequest"},"example":{"name":"Ideas","color":"indigo","type":"public"}}}},"responses":{"200":{"description":"Board updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardResponse"},"example":{"board":{"id":"brd_001","name":"Ideas","slug":"ideas","color":"indigo","type":"public","order":1}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Board not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Board name already exists or the organization plan does not support changing this board to private.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/BoardNameConflictErrorResponse"},{"$ref":"#/components/schemas/PlanFeatureUnavailableErrorResponse"}]},"examples":{"board_name_conflict":{"value":{"error":{"code":"board_name_conflict","message":"Board name already exists"}}},"plan_feature_unavailable":{"value":{"error":{"code":"plan_feature_unavailable","message":"Current plan does not support private boards","details":{"feature":"private_boards"}}}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"type","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"delete":{"operationId":"deleteBoard","tags":["Boards"],"summary":"Delete board","description":"Deletes a board by internal id. Boards that still have requests return a board_not_empty conflict.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"brd_001"},"required":true,"name":"board_id","in":"path"}],"responses":{"204":{"description":"Board deleted successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Board not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Board cannot be deleted because it still has requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardNotEmptyErrorResponse"},"example":{"error":{"code":"board_not_empty","message":"Cannot delete a board that still has requests"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/tags":{"get":{"operationId":"listRequestTags","tags":["Request Tags"],"summary":"List request tags","description":"Lists request tags for the authenticated organization. Returns all request tags; this collection is not paginated in v1.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Request tags returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestTagListResponse"},"example":{"tags":[{"id":"tag_001","name":"Enterprise"}]}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"createRequestTag","tags":["Request Tags"],"summary":"Create request tag","description":"Creates a request tag for the authenticated organization. Duplicate names return tag_name_conflict; exhausted request-tag quota returns plan_limit_reached.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRequestTagRequest"},"example":{"name":"Enterprise"}}}},"responses":{"201":{"description":"Request tag created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestTagResponse"},"example":{"tag":{"id":"tag_001","name":"Enterprise"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"A request tag with the same name already exists, or the organization has exhausted its request-tag quota.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/TagNameConflictErrorResponse"},{"$ref":"#/components/schemas/PlanLimitReachedErrorResponse"}]},"examples":{"tag_name_conflict":{"value":{"error":{"code":"tag_name_conflict","message":"Tag name already exists"}}},"plan_limit_reached":{"value":{"error":{"code":"plan_limit_reached","message":"Plan limit reached","details":{"resource":"feedback_tag","limit":5,"usage":5}}}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"name","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/tags/{tag_id}":{"delete":{"operationId":"deleteRequestTag","tags":["Request Tags"],"summary":"Delete request tag","description":"Deletes a request tag by internal id.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"tag_001"},"required":true,"name":"tag_id","in":"path"}],"responses":{"204":{"description":"Request tag deleted successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request tag not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests":{"get":{"operationId":"listRequests","tags":["Requests"],"summary":"List requests","description":"Lists requests with cursor pagination, search, sorting, and request-specific filters. sort=status_updated orders by the most recent status change, so sort=status_updated with statuses=closed returns recently closed requests first. author_id or author_external_id (not both) restricts results to requests whose author matches the member; an unknown member returns an empty page. This endpoint defaults to 10 items per page in v1 because request payloads embed richer related objects than lightweight relationship lists.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":10},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"search","in":"query"},{"schema":{"$ref":"#/components/schemas/RequestSort"},"required":false,"description":"Request list sort order. newest and oldest order by creation time. top orders by vote count, highest first. status_updated orders by the most recent status change first; combine with statuses to list recently closed or completed requests.","name":"sort","in":"query"},{"schema":{"$ref":"#/components/schemas/PublicId"},"required":false,"description":"Opaque UserJot resource identifier.","name":"author_id","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"author_external_id","in":"query"},{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PublicId"}},"required":false,"name":"board_ids","in":"query","style":"form","explode":true},{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RequestStatus"}},"required":false,"name":"statuses","in":"query","style":"form","explode":true},{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PublicId"}},"required":false,"name":"tag_ids","in":"query","style":"form","explode":true}],"responses":{"200":{"description":"Requests returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestListResponse"},"example":{"requests":[{"id":"req_001","title":"Support SAML single sign-on","body":"Enterprise teams need SAML SSO for secure rollout and centralized access control.","status":"planned","board":{"id":"brd_001","name":"Ideas","slug":"ideas","color":"indigo","type":"public"},"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"tags":[{"id":"tag_001","name":"Enterprise"}],"attachments":[{"id":"att_001","url":"https://assets.userjot.com/examples/saml-setup.png"}],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","status_updated_at":"2026-03-25T09:30:00.000Z","vote_count":12,"comment_count":3}],"next_cursor":"cursor_2"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"sort","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"createRequest","tags":["Requests"],"summary":"Create request","description":"Creates a request. This route supports optional Idempotency-Key handling and does not implicitly add votes, subscriptions, or auto-tags.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":false,"description":"Idempotency key for selected create routes.","name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRequestRequest"},"example":{"author":{"external_id":"maya.chen"},"board_id":"brd_001","title":"Support SAML single sign-on","body":"Enterprise teams need SAML SSO for secure rollout and centralized access control.","tag_ids":["tag_001"],"attachment_urls":["https://assets.userjot.com/examples/saml-setup.png"],"status":"planned"}}}},"responses":{"201":{"description":"Request created successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestResponse"},"example":{"request":{"id":"req_001","title":"Support SAML single sign-on","body":"Enterprise teams need SAML SSO for secure rollout and centralized access control.","status":"planned","board":{"id":"brd_001","name":"Ideas","slug":"ideas","color":"indigo","type":"public"},"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"tags":[{"id":"tag_001","name":"Enterprise"}],"attachments":[{"id":"att_001","url":"https://assets.userjot.com/examples/saml-setup.png"}],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-24T12:00:00.000Z","status_updated_at":"2026-03-24T12:00:00.000Z","vote_count":0,"comment_count":0}}}}},"401":{"description":"API token is missing, invalid, or inactive.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}}},"404":{"description":"Referenced member, board, or tag was not found.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}}},"409":{"description":"Idempotency conflict.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}},"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/IdempotencyKeyReusedErrorResponse"},{"$ref":"#/components/schemas/IdempotencyInProgressErrorResponse"},{"$ref":"#/components/schemas/MemberErasedErrorResponse"}]},"examples":{"key_reused":{"value":{"error":{"code":"idempotency_key_reused","message":"Idempotency key was reused with a different request"}}},"in_progress":{"value":{"error":{"code":"idempotency_in_progress","message":"A request with the same idempotency key is already in progress"}}}}}}},"422":{"description":"Request validation or attachment validation failed.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/InvalidAttachmentErrorResponse"}]},"example":{"error":{"code":"invalid_attachment","message":"Attachment URLs must use HTTPS"}}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}}}}}},"/requests/{request_id}":{"get":{"operationId":"getRequest","tags":["Requests"],"summary":"Get request","description":"Retrieves a single request by internal id.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"responses":{"200":{"description":"Request returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestResponse"},"example":{"request":{"id":"req_001","title":"Support SAML single sign-on","body":"Enterprise teams need SAML SSO for secure rollout and centralized access control.","status":"planned","board":{"id":"brd_001","name":"Ideas","slug":"ideas","color":"indigo","type":"public"},"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"tags":[{"id":"tag_001","name":"Enterprise"}],"attachments":[{"id":"att_001","url":"https://assets.userjot.com/examples/saml-setup.png"}],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","status_updated_at":"2026-03-25T09:30:00.000Z","vote_count":12,"comment_count":3}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"patch":{"operationId":"updateRequest","tags":["Requests"],"summary":"Update request","description":"Updates request core fields only. Status, board, tags, and attachments are managed through dedicated routes.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRequestRequest"},"example":{"title":"Support SAML single sign-on","body":"Enterprise teams need SAML SSO for secure rollout and centralized access control."}}}},"responses":{"200":{"description":"Request updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestResponse"},"example":{"request":{"id":"req_001","title":"Support SAML single sign-on","body":"Enterprise teams need SAML SSO for secure rollout and centralized access control.","status":"planned","board":{"id":"brd_001","name":"Ideas","slug":"ideas","color":"indigo","type":"public"},"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"tags":[{"id":"tag_001","name":"Enterprise"}],"attachments":[{"id":"att_001","url":"https://assets.userjot.com/examples/saml-setup.png"}],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","status_updated_at":"2026-03-25T09:30:00.000Z","vote_count":12,"comment_count":3}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"title","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"delete":{"operationId":"deleteRequest","tags":["Requests"],"summary":"Delete request","description":"Deletes a request by internal id.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"responses":{"204":{"description":"Request deleted successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/similar":{"get":{"operationId":"listSimilarRequests","tags":["Requests"],"summary":"List similar requests","description":"Returns up to limit requests most similar to the given request, ranked by embedding cosine similarity in descending order, excluding the source request and merged duplicates. Results honor board_ids, statuses, and tag_ids filters. Embeddings are generated asynchronously after a request is created or edited, so a very new request may return an empty list until its embedding exists. This endpoint is not paginated.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":50,"default":10},"required":false,"name":"limit","in":"query"},{"schema":{"type":"number","minimum":0,"maximum":1,"default":0.5},"required":false,"name":"min_similarity","in":"query"},{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PublicId"}},"required":false,"name":"board_ids","in":"query","style":"form","explode":true},{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RequestStatus"}},"required":false,"name":"statuses","in":"query","style":"form","explode":true},{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PublicId"}},"required":false,"name":"tag_ids","in":"query","style":"form","explode":true}],"responses":{"200":{"description":"Similar requests returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SimilarRequestsResponse"},"example":{"requests":[{"id":"req_001","title":"Support SAML single sign-on","body":"Enterprise teams need SAML SSO for secure rollout and centralized access control.","status":"planned","board":{"id":"brd_001","name":"Ideas","slug":"ideas","color":"indigo","type":"public"},"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"tags":[{"id":"tag_001","name":"Enterprise"}],"attachments":[{"id":"att_001","url":"https://assets.userjot.com/examples/saml-setup.png"}],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","status_updated_at":"2026-03-25T09:30:00.000Z","vote_count":12,"comment_count":3,"similarity":0.8731}]}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"min_similarity","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/status":{"patch":{"operationId":"updateRequestStatus","tags":["Request Workflow"],"summary":"Update request status","description":"Updates request status through a dedicated workflow route. Actor attribution is optional.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRequestStatusRequest"},"example":{"status":"completed","actor":{"external_id":"jonah.reed"}}}}},"responses":{"200":{"description":"Request status updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request or actor was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"status","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/board":{"patch":{"operationId":"moveRequestBoard","tags":["Request Workflow"],"summary":"Move request board","description":"Moves a request to another board through a dedicated workflow route. Actor attribution is optional.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveRequestBoardRequest"},"example":{"board_id":"brd_002","actor":{"external_id":"jonah.reed"}}}}},"responses":{"200":{"description":"Request board updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request, board, or actor was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"board_id","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/attachments":{"get":{"operationId":"listRequestAttachments","tags":["Request Attachments"],"summary":"List request attachments","description":"Lists attachments attached to a request. Returns all attachments; this list is not paginated in v1 because requests are capped at four attachments.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"responses":{"200":{"description":"Request attachments returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestAttachmentsResponse"},"example":{"attachments":[{"id":"att_001","url":"https://assets.userjot.com/examples/saml-setup.png"}]}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"addRequestAttachments","tags":["Request Attachments"],"summary":"Add request attachments","description":"Adds image attachments to a request. The request-level total attachment cap is enforced by the server.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRequestAttachmentsRequest"},"example":{"attachment_urls":["https://assets.userjot.com/examples/saml-setup.png"]}}}},"responses":{"200":{"description":"Request attachments added successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation or attachment validation failed.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/InvalidAttachmentErrorResponse"}]},"example":{"error":{"code":"invalid_attachment","message":"Attachment URLs must use HTTPS"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/attachments/{attachment_id}":{"delete":{"operationId":"deleteRequestAttachment","tags":["Request Attachments"],"summary":"Delete request attachment","description":"Removes an attachment from a request. If the attachment link is already absent, the operation succeeds without error.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"att_001"},"required":true,"name":"attachment_id","in":"path"}],"responses":{"204":{"description":"Request attachment deleted successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/comments":{"get":{"operationId":"listRequestComments","tags":["Request Comments"],"summary":"List request comments","description":"Lists top-level comments for a request with inline replies and cursor pagination for top-level comments only.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Request comments returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestCommentsResponse"},"example":{"comments":[{"id":"cmt_001","body":"This would make procurement and security review much easier for us.","parent_id":null,"visibility":"public","pinned":false,"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"attachments":[],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","vote_count":4,"replies":[{"id":"cmt_002","body":"Agreed. We hear this often from larger teams evaluating UserJot.","parent_id":"cmt_001","visibility":"public","pinned":false,"author":{"id":"mem_002","external_id":"jonah.reed","type":"admin","email":"jonah@northstar.com","first_name":"Jonah","last_name":"Reed","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","traits":{"monthlySpend":299,"plan":"professional","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"attachments":[],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","vote_count":1}]}],"next_cursor":"cursor_2"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"limit","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"createRequestComment","tags":["Request Comments"],"summary":"Create request comment","description":"Creates a top-level comment or reply on a request. Replies may only target top-level comments on the same request.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRequestCommentRequest"},"example":{"author":{"external_id":"maya.chen"},"body":"This would make procurement and security review much easier for us.","attachment_urls":["https://assets.userjot.com/examples/saml-setup.png"],"visibility":"public"}}}},"responses":{"201":{"description":"Request comment created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentResponse"},"example":{"comment":{"id":"cmt_001","body":"This would make procurement and security review much easier for us.","parent_id":null,"visibility":"public","pinned":false,"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"attachments":[{"id":"att_001","url":"https://assets.userjot.com/examples/saml-setup.png"}],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-24T12:00:00.000Z","vote_count":0}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request or author was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation, attachment validation, or parent-comment validation failed.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/InvalidParentCommentErrorResponse"},{"$ref":"#/components/schemas/InvalidAttachmentErrorResponse"}]},"example":{"error":{"code":"invalid_parent_comment","message":"parent_id must reference a top-level comment"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/comments/{comment_id}":{"get":{"operationId":"getComment","tags":["Request Comments"],"summary":"Get comment","description":"Retrieves a single comment by internal id under its request.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"}],"responses":{"200":{"description":"Comment returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentResponse"},"example":{"comment":{"id":"cmt_001","body":"This would make rollout much smoother for our team.","parent_id":null,"visibility":"public","pinned":false,"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"attachments":[],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","vote_count":4}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"patch":{"operationId":"updateComment","tags":["Request Comments"],"summary":"Update comment","description":"Updates a request comment body only. Visibility, attachments, votes, and pin state are managed through dedicated routes.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommentRequest"},"example":{"body":"This would make rollout much smoother for our team."}}}},"responses":{"200":{"description":"Comment updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentResponse"},"example":{"comment":{"id":"cmt_001","body":"This would make rollout much smoother for our team.","parent_id":null,"visibility":"public","pinned":false,"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"attachments":[],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","vote_count":4}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"body","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"delete":{"operationId":"deleteComment","tags":["Request Comments"],"summary":"Delete comment","description":"Deletes a request comment by internal id.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"}],"responses":{"204":{"description":"Comment deleted successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/comments/{comment_id}/attachments":{"get":{"operationId":"listCommentAttachments","tags":["Request Comment Attachments"],"summary":"List comment attachments","description":"Lists attachments attached to a request comment. Returns all attachments; this list is not paginated in v1 because comments are capped at four attachments.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"}],"responses":{"200":{"description":"Comment attachments returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentAttachmentsResponse"},"example":{"attachments":[{"id":"att_001","url":"https://assets.userjot.com/examples/saml-setup.png"}]}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"addCommentAttachments","tags":["Request Comment Attachments"],"summary":"Add comment attachments","description":"Adds image attachments to a request comment. The comment-level total attachment cap is enforced by the server.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCommentAttachmentsRequest"},"example":{"attachment_urls":["https://assets.userjot.com/examples/saml-setup.png"]}}}},"responses":{"200":{"description":"Comment attachments added successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation or attachment validation failed.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/InvalidAttachmentErrorResponse"}]},"example":{"error":{"code":"invalid_attachment","message":"Attachment URLs must use HTTPS"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/comments/{comment_id}/attachments/{attachment_id}":{"delete":{"operationId":"deleteCommentAttachment","tags":["Request Comment Attachments"],"summary":"Delete comment attachment","description":"Removes an attachment from a request comment. If the attachment link is already absent, the operation succeeds without error.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"att_001"},"required":true,"name":"attachment_id","in":"path"}],"responses":{"204":{"description":"Comment attachment deleted successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/comments/{comment_id}/votes":{"get":{"operationId":"listCommentVotes","tags":["Request Comment Votes"],"summary":"List comment votes","description":"Lists request comment votes ordered newest-first with cursor pagination.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"},{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Comment votes returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentVotesResponse"},"example":{"votes":[{"voter":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"created_at":"2026-03-24T12:00:00.000Z"}],"next_cursor":"cursor_2"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"limit","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"addCommentVote","tags":["Request Comment Votes"],"summary":"Add comment vote","description":"Adds a vote to a request comment for an existing member.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCommentVoteRequest"},"example":{"voter":{"external_id":"maya.chen"}}}}},"responses":{"200":{"description":"Comment vote added successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment or voter was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"voter","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"delete":{"operationId":"deleteCommentVote","tags":["Request Comment Votes"],"summary":"Delete comment vote","description":"Removes a vote from a request comment. Exactly one of voter_id or voter_external_id must be provided.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"},{"schema":{"$ref":"#/components/schemas/PublicId"},"required":false,"description":"Opaque UserJot resource identifier.","name":"voter_id","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"voter_external_id","in":"query"}],"responses":{"204":{"description":"Comment vote removed successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"400":{"description":"Request query parameters are invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidRequestErrorResponse"},"example":{"error":{"code":"invalid_request","message":"Invalid request"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment or voter was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/comments/{comment_id}/pin":{"put":{"operationId":"pinComment","tags":["Request Comments"],"summary":"Pin comment","description":"Pins a request comment. This route updates pin state only and does not require an actor payload.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"}],"responses":{"200":{"description":"Comment pinned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"delete":{"operationId":"unpinComment","tags":["Request Comments"],"summary":"Unpin comment","description":"Unpins a request comment. This route updates pin state only and does not require an actor payload.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"cmt_001"},"required":true,"name":"comment_id","in":"path"}],"responses":{"204":{"description":"Comment unpinned successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Comment not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/votes":{"get":{"operationId":"listRequestVotes","tags":["Request Votes"],"summary":"List request votes","description":"Lists request votes ordered newest-first with cursor pagination.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Request votes returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestVotesResponse"},"example":{"votes":[{"voter":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"created_at":"2026-03-24T12:00:00.000Z"}],"next_cursor":"cursor_2"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"limit","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"addRequestVote","tags":["Request Votes"],"summary":"Add request vote","description":"Adds a vote to a request for an existing member.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRequestVoteRequest"},"example":{"voter":{"external_id":"maya.chen"}}}}},"responses":{"200":{"description":"Request vote added successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request or voter was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"voter","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"delete":{"operationId":"deleteRequestVote","tags":["Request Votes"],"summary":"Delete request vote","description":"Removes a vote from a request. Exactly one of voter_id or voter_external_id must be provided.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"$ref":"#/components/schemas/PublicId"},"required":false,"description":"Opaque UserJot resource identifier.","name":"voter_id","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"voter_external_id","in":"query"}],"responses":{"204":{"description":"Request vote removed successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"400":{"description":"Request query parameters are invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidRequestErrorResponse"},"example":{"error":{"code":"invalid_request","message":"Invalid request"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request or voter was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/subscriptions":{"get":{"operationId":"listRequestSubscriptions","tags":["Request Subscriptions"],"summary":"List request subscriptions","description":"Lists request subscriptions ordered newest-first with cursor pagination.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Request subscriptions returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestSubscriptionsResponse"},"example":{"subscriptions":[{"subscriber":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"created_at":"2026-03-24T12:00:00.000Z"}],"next_cursor":"cursor_2"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"limit","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"addRequestSubscription","tags":["Request Subscriptions"],"summary":"Add request subscription","description":"Subscribes an existing member to a request.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRequestSubscriptionRequest"},"example":{"subscriber":{"external_id":"maya.chen"}}}}},"responses":{"200":{"description":"Request subscription added successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request or subscriber was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"subscriber","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"delete":{"operationId":"deleteRequestSubscription","tags":["Request Subscriptions"],"summary":"Delete request subscription","description":"Removes a subscription from a request. Exactly one of subscriber_id or subscriber_external_id must be provided.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"$ref":"#/components/schemas/PublicId"},"required":false,"description":"Opaque UserJot resource identifier.","name":"subscriber_id","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"subscriber_external_id","in":"query"}],"responses":{"204":{"description":"Request subscription removed successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"400":{"description":"Request query parameters are invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidRequestErrorResponse"},"example":{"error":{"code":"invalid_request","message":"Invalid request"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request or subscriber was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/tags":{"get":{"operationId":"listRequestTagAssignments","tags":["Request Tags"],"summary":"List request tags","description":"Lists tags attached to a request. Returns all attached tags; this relationship list is not paginated in v1.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"responses":{"200":{"description":"Request tags returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestTagsResponse"},"example":{"tags":[{"id":"tag_001","name":"Enterprise"}]}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"addRequestTags","tags":["Request Tags"],"summary":"Add request tags","description":"Adds one or more tags to a request.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRequestTagsRequest"},"example":{"tag_ids":["tag_001"]}}}},"responses":{"200":{"description":"Request tags added successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request or tag was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"tag_ids","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/requests/{request_id}/tags/{tag_id}":{"delete":{"operationId":"deleteRequestTagAssignment","tags":["Request Tags"],"summary":"Delete request tag","description":"Removes a tag from a request.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"tag_001"},"required":true,"name":"tag_id","in":"path"}],"responses":{"204":{"description":"Request tag removed successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Request or tag was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/changelogs/tags":{"get":{"operationId":"listChangelogTags","tags":["Changelog Tags"],"summary":"List changelog tags","description":"Lists changelog tags for the authenticated organization. Returns all changelog tags; this collection is not paginated in v1.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Changelog tags returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangelogTagListResponse"},"example":{"tags":[{"id":"tag_002","name":"Polish"}]}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"createChangelogTag","tags":["Changelog Tags"],"summary":"Create changelog tag","description":"Creates a changelog tag for the authenticated organization. Duplicate names return tag_name_conflict; exhausted changelog-tag quota returns plan_limit_reached.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChangelogTagRequest"},"example":{"name":"Polish"}}}},"responses":{"201":{"description":"Changelog tag created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangelogTagResponse"},"example":{"tag":{"id":"tag_002","name":"Polish"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"A changelog tag with the same name already exists, or the organization has exhausted its changelog-tag quota.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/TagNameConflictErrorResponse"},{"$ref":"#/components/schemas/PlanLimitReachedErrorResponse"}]},"examples":{"tag_name_conflict":{"value":{"error":{"code":"tag_name_conflict","message":"Tag name already exists"}}},"plan_limit_reached":{"value":{"error":{"code":"plan_limit_reached","message":"Plan limit reached","details":{"resource":"changelog_tag","limit":5,"usage":5}}}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"name","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/changelogs/tags/{tag_id}":{"delete":{"operationId":"deleteChangelogTag","tags":["Changelog Tags"],"summary":"Delete changelog tag","description":"Deletes a changelog tag by internal id.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"tag_001"},"required":true,"name":"tag_id","in":"path"}],"responses":{"204":{"description":"Changelog tag deleted successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog tag not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/changelogs":{"get":{"operationId":"listChangelogs","tags":["Changelogs"],"summary":"List changelogs","description":"Lists changelog entries with cursor pagination, search, and status filtering. Draft entries are included because this is an admin API. The virtual scheduled filter matches entries whose persisted status is published and whose publish_at is still in the future; returned items still serialize with status: published. This endpoint defaults to 10 items per page in v1 because changelog payloads embed richer related objects than lightweight relationship lists.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":10},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"search","in":"query"},{"schema":{"$ref":"#/components/schemas/ChangelogStatusFilter"},"required":false,"description":"List filter for changelog status, including virtual scheduled. The scheduled filter matches entries whose persisted status is published and whose publish_at is still in the future.","name":"status","in":"query"}],"responses":{"200":{"description":"Changelog entries returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangelogListResponse"},"example":{"changelogs":[{"id":"chg_001","title":"SAML SSO is now available","markdown":"## What shipped\n\nSAML SSO is now available for Professional workspaces.","short":"Enterprise teams can now sign in with their identity provider.","cover":null,"status":"published","publish_at":"2026-03-26T15:00:00.000Z","created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","tags":[{"id":"tag_002","name":"Polish"}],"authors":[{"id":"mem_002","external_id":"jonah.reed","type":"admin","email":"jonah@northstar.com","first_name":"Jonah","last_name":"Reed","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","traits":{"monthlySpend":299,"plan":"professional","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}]}],"next_cursor":"cursor_2"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"status","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"createChangelog","tags":["Changelogs"],"summary":"Create changelog","description":"Creates a changelog entry from markdown content. Inline authors are optional, but when provided they must resolve to existing user-backed owner/admin members in the same organization. cover_asset_id must reference an asset from POST /assets or POST /assets/import in the same workspace; unknown ids return 404 not_found. This route supports optional Idempotency-Key handling.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":false,"description":"Idempotency key for selected create routes.","name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChangelogRequest"},"example":{"title":"SAML SSO is now available","markdown":"## What shipped\n\nSAML SSO is now available for Professional workspaces.","short":"Enterprise teams can now sign in with their identity provider.","cover_asset_id":"ast_001","status":"published","publish_at":"2026-03-26T15:00:00.000Z","authors":[{"external_id":"jonah.reed"}],"tag_ids":["tag_002"],"request_ids":["req_001"]}}}},"responses":{"201":{"description":"Changelog created successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangelogResponse"},"example":{"changelog":{"id":"chg_001","title":"SAML SSO is now available","markdown":"## What shipped\n\nSAML SSO is now available for Professional workspaces.","short":"Enterprise teams can now sign in with their identity provider.","cover":{"id":"ast_001","url":"https://cdn.userjot.com/orgs/org_001/assets/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08/original.png","name":"hero.png","content_type":"image/png","size_bytes":184213,"kind":"image","image":{"width":1600,"height":838},"created_at":"2026-03-26T00:00:00.000Z"},"status":"published","publish_at":"2026-03-26T15:00:00.000Z","created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z"}}}}},"401":{"description":"API token is missing, invalid, or inactive.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}}},"404":{"description":"Referenced cover asset, author, tag, or request was not found.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}}},"409":{"description":"Idempotency conflict.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}},"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/IdempotencyKeyReusedErrorResponse"},{"$ref":"#/components/schemas/IdempotencyInProgressErrorResponse"}]},"examples":{"key_reused":{"value":{"error":{"code":"idempotency_key_reused","message":"Idempotency key was reused with a different request"}}},"in_progress":{"value":{"error":{"code":"idempotency_in_progress","message":"A request with the same idempotency key is already in progress"}}}}}}},"422":{"description":"Request validation failed, or one or more supplied authors were not eligible changelog authors. Changelog authors must be existing user-backed owner/admin members.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/InvalidChangelogAuthorErrorResponse"}]},"example":{"error":{"code":"invalid_changelog_author","message":"Changelog authors must be owner or admin members"}}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}}}}}},"/changelogs/{changelog_id}":{"get":{"operationId":"getChangelog","tags":["Changelogs"],"summary":"Get changelog","description":"Retrieves a single changelog entry by internal id, including tags, authors, and linked requests.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"}],"responses":{"200":{"description":"Changelog returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangelogDetailResponse"},"example":{"changelog":{"id":"chg_001","title":"SAML SSO is now available","markdown":"## What shipped\n\nSAML SSO is now available for Professional workspaces.","short":"Enterprise teams can now sign in with their identity provider.","cover":{"id":"ast_001","url":"https://cdn.userjot.com/orgs/org_001/assets/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08/original.png","name":"hero.png","content_type":"image/png","size_bytes":184213,"kind":"image","image":{"width":1600,"height":838},"created_at":"2026-03-26T00:00:00.000Z"},"status":"published","publish_at":"2026-03-26T15:00:00.000Z","created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","tags":[{"id":"tag_002","name":"Polish"}],"authors":[{"id":"mem_002","external_id":"jonah.reed","type":"admin","email":"jonah@northstar.com","first_name":"Jonah","last_name":"Reed","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","traits":{"monthlySpend":299,"plan":"professional","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}],"requests":[{"id":"req_001","title":"Support SAML single sign-on","body":"Enterprise teams need SAML SSO for secure rollout and centralized access control.","status":"planned","board":{"id":"brd_001","name":"Ideas","slug":"ideas","color":"indigo","type":"public"},"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"tags":[{"id":"tag_001","name":"Enterprise"}],"attachments":[{"id":"att_001","url":"https://assets.userjot.com/examples/saml-setup.png"}],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","status_updated_at":"2026-03-25T09:30:00.000Z","vote_count":12,"comment_count":3}]}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"patch":{"operationId":"updateChangelog","tags":["Changelogs"],"summary":"Update changelog","description":"Updates changelog core fields only. cover_asset_id must reference an asset from POST /assets or POST /assets/import in the same workspace; null clears the cover and unknown ids return 404 not_found. Tags, authors, and linked requests are managed through dedicated routes.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateChangelogRequest"},"example":{"title":"SAML SSO is now available","short":"Enterprise teams can now sign in with their identity provider.","markdown":"## What shipped\n\nSAML SSO is now available for Professional workspaces.","status":"published","publish_at":"2026-03-26T15:00:00.000Z"}}}},"responses":{"200":{"description":"Changelog updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangelogResponse"},"example":{"changelog":{"id":"chg_001","title":"SAML SSO is now available","markdown":"## What shipped\n\nSAML SSO is now available for Professional workspaces.","short":"Enterprise teams can now sign in with their identity provider.","cover":{"id":"ast_001","url":"https://cdn.userjot.com/orgs/org_001/assets/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08/original.png","name":"hero.png","content_type":"image/png","size_bytes":184213,"kind":"image","image":{"width":1600,"height":838},"created_at":"2026-03-26T00:00:00.000Z"},"status":"published","publish_at":"2026-03-26T15:00:00.000Z","created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"title","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"delete":{"operationId":"deleteChangelog","tags":["Changelogs"],"summary":"Delete changelog","description":"Deletes a changelog entry by internal id.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"}],"responses":{"204":{"description":"Changelog deleted successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/changelogs/{changelog_id}/tags":{"get":{"operationId":"listChangelogTagAssignments","tags":["Changelog Tags"],"summary":"List changelog tags","description":"Lists tags attached to a changelog entry. Returns all attached tags; this relationship list is not paginated in v1.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"}],"responses":{"200":{"description":"Changelog tags returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangelogTagsResponse"},"example":{"tags":[{"id":"tag_002","name":"Polish"}]}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"addChangelogTags","tags":["Changelog Tags"],"summary":"Add changelog tags","description":"Adds one or more tags to a changelog entry.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddChangelogTagsRequest"},"example":{"tag_ids":["tag_002"]}}}},"responses":{"200":{"description":"Changelog tags added successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog or tag was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"tag_ids","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/changelogs/{changelog_id}/tags/{tag_id}":{"delete":{"operationId":"deleteChangelogTagAssignment","tags":["Changelog Tags"],"summary":"Delete changelog tag","description":"Removes a tag from a changelog entry.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"tag_001"},"required":true,"name":"tag_id","in":"path"}],"responses":{"204":{"description":"Changelog tag removed successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog or tag was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/changelogs/{changelog_id}/authors":{"get":{"operationId":"listChangelogAuthors","tags":["Changelog Authors"],"summary":"List changelog authors","description":"Lists authors attached to a changelog entry. Returns all authors; this relationship list is not paginated in v1.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"}],"responses":{"200":{"description":"Changelog authors returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangelogAuthorsResponse"},"example":{"authors":[{"id":"mem_002","external_id":"jonah.reed","type":"admin","email":"jonah@northstar.com","first_name":"Jonah","last_name":"Reed","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","traits":{"monthlySpend":299,"plan":"professional","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}]}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"addChangelogAuthors","tags":["Changelog Authors"],"summary":"Add changelog authors","description":"Adds one or more authors to a changelog entry. Every supplied author must resolve to an existing user-backed owner/admin member in the same organization.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddChangelogAuthorsRequest"},"example":{"authors":[{"external_id":"jonah.reed"}]}}}},"responses":{"200":{"description":"Changelog authors added successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog or author was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed, or one or more supplied authors were not eligible changelog authors. Changelog authors must be existing user-backed owner/admin members.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/InvalidChangelogAuthorErrorResponse"}]},"example":{"error":{"code":"invalid_changelog_author","message":"Changelog authors must be owner or admin members"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/changelogs/{changelog_id}/authors/{member_id}":{"delete":{"operationId":"deleteChangelogAuthor","tags":["Changelog Authors"],"summary":"Delete changelog author","description":"Removes an author from a changelog entry.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"mem_001"},"required":true,"name":"member_id","in":"path"}],"responses":{"204":{"description":"Changelog author removed successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog or author was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/changelogs/{changelog_id}/requests":{"get":{"operationId":"listChangelogRequests","tags":["Changelog Requests"],"summary":"List changelog requests","description":"Lists requests linked to a changelog entry. Returns all linked requests; this relationship list is not paginated in v1.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"}],"responses":{"200":{"description":"Linked requests returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangelogRequestsResponse"},"example":{"requests":[{"id":"req_001","title":"Support SAML single sign-on","body":"Enterprise teams need SAML SSO for secure rollout and centralized access control.","status":"planned","board":{"id":"brd_001","name":"Ideas","slug":"ideas","color":"indigo","type":"public"},"author":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},"tags":[{"id":"tag_001","name":"Enterprise"}],"attachments":[{"id":"att_001","url":"https://assets.userjot.com/examples/saml-setup.png"}],"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z","status_updated_at":"2026-03-25T09:30:00.000Z","vote_count":12,"comment_count":3}]}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"addChangelogRequests","tags":["Changelog Requests"],"summary":"Add changelog requests","description":"Links one or more requests to a changelog entry.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddChangelogRequestsRequest"},"example":{"request_ids":["req_001"]}}}},"responses":{"200":{"description":"Requests linked successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog or request was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"request_ids","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/changelogs/{changelog_id}/requests/{request_id}":{"delete":{"operationId":"deleteChangelogRequest","tags":["Changelog Requests"],"summary":"Delete changelog request","description":"Removes a linked request from a changelog entry.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"chg_001"},"required":true,"name":"changelog_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"req_001"},"required":true,"name":"request_id","in":"path"}],"responses":{"204":{"description":"Linked request removed successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Changelog or request was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/assets":{"post":{"operationId":"createAsset","tags":["Assets"],"summary":"Upload asset","description":"Assets are org-owned and permanent. Accepted images are image/png, image/jpeg, image/gif, and image/webp, up to 10 MiB. Identical bytes create a new id with the same URL.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateAssetForm"}}}},"responses":{"201":{"description":"Asset returned successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetResponse"},"example":{"asset":{"id":"ast_001","url":"https://cdn.userjot.com/orgs/org_001/assets/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08/original.png","name":"hero.png","content_type":"image/png","size_bytes":184213,"kind":"image","image":{"width":1600,"height":838},"created_at":"2026-03-26T00:00:00.000Z"}}}}},"401":{"description":"API token is missing, invalid, or inactive.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}}},"422":{"description":"Request validation failed or the image could not be ingested.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/InvalidAssetErrorResponse"}]},"example":{"error":{"code":"invalid_asset","message":"Asset content type is not supported"}}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}}}}}},"/assets/import":{"post":{"operationId":"importAsset","tags":["Assets"],"summary":"Import asset","description":"Assets are org-owned and permanent. Accepted images are image/png, image/jpeg, image/gif, and image/webp, up to 10 MiB. Identical bytes create a new id with the same URL. The URL must use HTTPS and be publicly reachable; redirects are followed up to three hops. Supports the optional Idempotency-Key header.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":false,"description":"Idempotency key for selected create routes.","name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportAssetRequest"},"example":{"url":"https://example.com/images/hero.png","name":"hero.png"}}}},"responses":{"201":{"description":"Asset returned successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetResponse"},"example":{"asset":{"id":"ast_001","url":"https://cdn.userjot.com/orgs/org_001/assets/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08/original.png","name":"hero.png","content_type":"image/png","size_bytes":184213,"kind":"image","image":{"width":1600,"height":838},"created_at":"2026-03-26T00:00:00.000Z"}}}}},"401":{"description":"API token is missing, invalid, or inactive.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}}},"409":{"description":"Idempotency key conflicts with an earlier or in-flight request.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}},"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/IdempotencyKeyReusedErrorResponse"},{"$ref":"#/components/schemas/IdempotencyInProgressErrorResponse"}]},"examples":{"reused":{"value":{"error":{"code":"idempotency_key_reused","message":"Idempotency key was reused with a different request"}}},"in_progress":{"value":{"error":{"code":"idempotency_in_progress","message":"A request with the same idempotency key is already in progress"}}}}}}},"422":{"description":"Request validation failed or the image could not be ingested.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ValidationErrorResponse"},{"$ref":"#/components/schemas/InvalidAssetErrorResponse"}]},"example":{"error":{"code":"invalid_asset","message":"Asset content type is not supported"}}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}}}}}},"/assets/{asset_id}":{"get":{"operationId":"getAsset","tags":["Assets"],"summary":"Get asset","description":"Assets are org-owned and permanent. Accepted images are image/png, image/jpeg, image/gif, and image/webp, up to 10 MiB. Identical bytes create a new id with the same URL.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"ast_001"},"required":true,"name":"asset_id","in":"path"}],"responses":{"200":{"description":"Asset returned successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetResponse"},"example":{"asset":{"id":"ast_001","url":"https://cdn.userjot.com/orgs/org_001/assets/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08/original.png","name":"hero.png","content_type":"image/png","size_bytes":184213,"kind":"image","image":{"width":1600,"height":838},"created_at":"2026-03-26T00:00:00.000Z"}}}}},"401":{"description":"API token is missing, invalid, or inactive.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}}},"404":{"description":"Asset not found.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}}}}}},"/members/{member_id}":{"delete":{"operationId":"deleteMember","tags":["Members"],"summary":"Erase member personal data","description":"Permanently erases personal data while retaining authored content and votes. Repeated deletion returns 204. Automated recreation by the erased email or external_id is blocked until an administrator lifts the block.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"mem_001"},"required":true,"name":"member_id","in":"path"}],"responses":{"204":{"description":"Member personal data erased.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Member not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Administrators and owners cannot be erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberNotErasableErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Member erasure failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"get":{"operationId":"getMember","tags":["Members"],"summary":"Get member","description":"Retrieves a single listable member by id. Guest and anonymous members are not returned.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"mem_001"},"required":true,"name":"member_id","in":"path"}],"responses":{"200":{"description":"Member returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberResponse"},"example":{"member":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Member not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"410":{"description":"Member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"patch":{"operationId":"updateMember","tags":["Members"],"summary":"Update member","description":"Partially updates a single listable member by id. Guest and anonymous members are not patchable. Traits are merged rather than replaced. avatar_url ingestion is eventually consistent, so the immediate response may still include the previous avatar_url.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"mem_001"},"required":true,"name":"member_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMemberRequest"},"example":{"external_id":"maya.chen.updated","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false}}}}},"responses":{"200":{"description":"Member updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberResponse"},"example":{"member":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Member not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Member identity or email conflict.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/MemberEmailConflictErrorResponse"},{"$ref":"#/components/schemas/MemberIdentityConflictErrorResponse"},{"$ref":"#/components/schemas/MemberErasedErrorResponse"}]},"examples":{"email_conflict":{"value":{"error":{"code":"member_email_conflict","message":"Email is already used by another member"}}},"identity_conflict":{"value":{"error":{"code":"member_identity_conflict","message":"The supplied external_id conflicts with an existing member matched by email"}}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"410":{"description":"Member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"avatar_url","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/members/sync":{"post":{"operationId":"syncMember","tags":["Members"],"summary":"Sync member","description":"Creates or updates a member by customer external_id. This upsert route always returns 200 and does not separately signal whether it created or updated the member. When creating a new member, omitted email and profile fields default to null. When updating an existing member, omitted fields are left unchanged, nullable fields may be cleared with null, and traits are merged rather than replaced. Inline companies may be synced for convenience and still require name when creating a new company entry. avatar_url ingestion is eventually consistent, so the immediate response may still include the previous avatar_url.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncMemberRequest"},"example":{"external_id":"maya.chen","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"companies":[{"external_id":"northstar","name":"Northstar","domain":"northstar.com","logo_url":"https://assets.userjot.com/examples/northstar.png","traits":{"monthlySpend":499,"plan":"professional","industry":"SaaS","companySize":42}}]}}}},"responses":{"200":{"description":"Member synced successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberResponse"},"example":{"member":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Member identity or email conflict.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/MemberIdentityConflictErrorResponse"},{"$ref":"#/components/schemas/MemberEmailConflictErrorResponse"},{"$ref":"#/components/schemas/MemberErasedErrorResponse"}]},"examples":{"identity_conflict":{"value":{"error":{"code":"member_identity_conflict","message":"The supplied external_id conflicts with an existing member matched by email"}}},"email_conflict":{"value":{"error":{"code":"member_email_conflict","message":"Email is already used by another member"}}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"external_id","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/members":{"get":{"operationId":"listMembers","tags":["Members"],"summary":"List members","description":"Lists listable members with cursor pagination, free-text search, and exact-match filters for type, external_id, email, and company_external_id. The exact email filter matches either the member email or the linked user email. Guest, anonymous, and erased members are excluded.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"search","in":"query"},{"schema":{"$ref":"#/components/schemas/ListableMemberType"},"required":false,"description":"Public member type returned by listable member endpoints.","name":"type","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"external_id","in":"query"},{"schema":{"type":"string","format":"email"},"required":false,"name":"email","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"company_external_id","in":"query"}],"responses":{"200":{"description":"Members returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembersListResponse"},"example":{"members":[{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"},{"id":"mem_002","external_id":"jonah.reed","type":"admin","email":"jonah@northstar.com","first_name":"Jonah","last_name":"Reed","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","traits":{"monthlySpend":299,"plan":"professional","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}],"next_cursor":"cursor_2"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"limit","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/members/lookup":{"get":{"operationId":"lookupMember","tags":["Members"],"summary":"Lookup member","description":"Resolves a listable member by either customer external_id or exact email. Email lookup matches either the member email or the linked user email. Guest and anonymous members are not returned.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":false,"name":"external_id","in":"query"},{"schema":{"type":"string","format":"email"},"required":false,"name":"email","in":"query"}],"responses":{"200":{"description":"Member returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberResponse"},"example":{"member":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"400":{"description":"The query shape is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidRequestErrorResponse"},"example":{"error":{"code":"invalid_request","message":"Invalid request"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Member not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The supplied email resolves to more than one member identity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberEmailConflictErrorResponse"},"example":{"error":{"code":"member_email_conflict","message":"Email is already used by another member"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"external_id","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/conversations":{"get":{"operationId":"listConversations","tags":["Conversations"],"summary":"List conversations","description":"Lists conversations newest-updated first. updated_since returns conversations whose updated_at is after the timestamp, which moves on new messages, notes, status changes, and assignments. To poll, pass a time one minute before your previous poll started and dedupe by id; edits to existing messages may not move updated_at. inbox_state is needs_team, ai_handling, or waiting_on_customer, and is null when the conversation is not open. Default statuses excludes spam. assignee_id is a member id. participant_id is a participants[].id from a previous response; participant_external_id and participant_email match a participant who is a member or an email sender. An unknown participant or assignee returns an empty page. Defaults to 20 per page, at most 100.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConversationStatus"}},"required":false,"name":"statuses","in":"query","style":"form","explode":true},{"schema":{"$ref":"#/components/schemas/ConversationInboxState"},"required":false,"name":"inbox_state","in":"query"},{"schema":{"allOf":[{"$ref":"#/components/schemas/PublicId"},{"description":"Member id of the current assignee."}]},"required":false,"description":"Member id of the current assignee.","name":"assignee_id","in":"query"},{"schema":{"allOf":[{"$ref":"#/components/schemas/PublicId"},{"description":"Identity handle from participants[].id."}]},"required":false,"description":"Identity handle from participants[].id.","name":"participant_id","in":"query"},{"schema":{"type":"string","minLength":1,"description":"external_id of a member who is a participant."},"required":false,"description":"external_id of a member who is a participant.","name":"participant_external_id","in":"query"},{"schema":{"type":"string","format":"email","description":"Case-insensitive match on a participant's email."},"required":false,"description":"Case-insensitive match on a participant's email.","name":"participant_email","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"updated_since","in":"query"}],"responses":{"200":{"description":"Conversations returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationListResponse"},"example":{"conversations":[{"id":"cnv_001","status":"open","inbox_state":"needs_team","source":"widget","subject":"Exporting feedback","preview":"How can I export our feedback?","participants":[{"id":"cid_001","type":"customer","name":"Maya Chen","email":"maya@northstar.com","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","member":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}}],"assignee":{"id":"cid_002","type":"team","name":"Jonah Reed","email":"jonah@northstar.com","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","member":{"id":"mem_002","external_id":"jonah.reed","type":"admin","email":"jonah@northstar.com","first_name":"Jonah","last_name":"Reed","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","traits":{"monthlySpend":299,"plan":"professional","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}},"snoozed_until":null,"resolved_at":null,"last_customer_message_at":"2026-03-24T12:00:00.000Z","last_reply_at":null,"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z"}],"next_cursor":null}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Query validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"participant_email","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/conversations/{conversation_id}":{"get":{"operationId":"getConversation","tags":["Conversations"],"summary":"Get conversation","description":"Returns a conversation in the workspace with its participants and assignee. Deleted and foreign conversations are not found.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cnv_001"},"required":true,"name":"conversation_id","in":"path"}],"responses":{"200":{"description":"Conversation returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationResponse"},"example":{"conversation":{"id":"cnv_001","status":"open","inbox_state":"needs_team","source":"widget","subject":"Exporting feedback","preview":"How can I export our feedback?","participants":[{"id":"cid_001","type":"customer","name":"Maya Chen","email":"maya@northstar.com","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","member":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}}],"assignee":{"id":"cid_002","type":"team","name":"Jonah Reed","email":"jonah@northstar.com","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","member":{"id":"mem_002","external_id":"jonah.reed","type":"admin","email":"jonah@northstar.com","first_name":"Jonah","last_name":"Reed","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","traits":{"monthlySpend":299,"plan":"professional","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}},"snoozed_until":null,"resolved_at":null,"last_customer_message_at":"2026-03-24T12:00:00.000Z","last_reply_at":null,"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Conversation not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Path validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"conversation_id","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/conversations/{conversation_id}/timeline":{"get":{"operationId":"listConversationTimeline","tags":["Conversations"],"summary":"List conversation timeline","description":"Returns the conversation's timeline oldest first. Entry type is one of message, note, ai_handoff, resolved, reopened, assigned, unassigned. message entries carry body (Markdown), attachments, edited_at, and an actor whose type says whether a customer, a team member, Juno, or automation wrote it; note is internal and has the same fields; ai_handoff carries the reason Juno handed off. types restricts the entry types, for example types=message for a transcript. New entry types may be added; treat unknown type values as opaque. Attachment URLs are signed and expire. Defaults to 50 per page, at most 100.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cnv_001"},"required":true,"name":"conversation_id","in":"path"},{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TimelineEntryType"}},"required":false,"name":"types","in":"query","style":"form","explode":true}],"responses":{"200":{"description":"Timeline returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationTimelineResponse"},"example":{"entries":[{"id":"evt_01","conversation_id":"cnv_01","type":"message","visibility":"public","actor":{"id":"cid_001","type":"customer","name":"Maya Chen","email":"maya@northstar.com","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","member":{"id":"mem_001","external_id":"maya.chen","type":"user"}},"created_at":"2026-01-02T03:04:05.000Z","body":"I need help exporting CSV","attachments":[],"edited_at":null},{"id":"evt_02","conversation_id":"cnv_01","type":"message","visibility":"public","actor":{"id":"cid_002","type":"team","name":"Jonah Reed","email":"jonah@northstar.com","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","member":{"id":"mem_002","external_id":"jonah.reed","type":"admin"}},"created_at":"2026-01-02T03:05:05.000Z","body":"Open **Settings** to export your data.","attachments":[],"edited_at":null},{"id":"evt_03","conversation_id":"cnv_01","type":"resolved","visibility":"public","actor":{"id":"cid_002","type":"team","name":"Jonah Reed","email":"jonah@northstar.com","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","member":{"id":"mem_002","external_id":"jonah.reed","type":"admin"}},"created_at":"2026-01-02T03:06:05.000Z","resolution_reason":"manual"}],"next_cursor":null}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Conversation not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"types","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/conversations/{conversation_id}/replies":{"post":{"operationId":"createConversationReply","tags":["Conversations"],"summary":"Create conversation reply","description":"Posts a public reply as the given team member. The actor must be an active workspace owner or admin. Replying to a resolved conversation reopens it. Archived and spam conversations cannot be replied to; set status to open first. Supports Idempotency-Key; a retried key returns the original reply and never posts twice.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cnv_001"},"required":true,"name":"conversation_id","in":"path"},{"schema":{"type":"string","minLength":1},"required":false,"description":"Idempotency key for selected create routes.","name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateConversationReplyRequest"},"example":{"actor":{"id":"mem_002"},"body":"Open **Settings** to export your data."}}}},"responses":{"201":{"description":"Entry created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationEntryResponse"},"example":{"entry":{"id":"evt_02","conversation_id":"cnv_01","type":"message","visibility":"public","actor":{"id":"cid_002","type":"team","name":"Jonah Reed","email":"jonah@northstar.com","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","member":{"id":"mem_002","external_id":"jonah.reed","type":"admin"}},"created_at":"2026-01-02T03:05:05.000Z","body":"Open **Settings** to export your data.","attachments":[],"edited_at":null}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Conversation or actor not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Conversation status, erased member, or idempotency conflict.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}},"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ConversationStatusConflictErrorResponse"},{"$ref":"#/components/schemas/MemberErasedErrorResponse"},{"$ref":"#/components/schemas/IdempotencyKeyReusedErrorResponse"},{"$ref":"#/components/schemas/IdempotencyInProgressErrorResponse"}]},"example":{"error":{"code":"conversation_status_conflict","message":"Only open conversations can receive team replies"}}}}},"422":{"description":"Actor or request validation failed.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/InvalidConversationActorErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"actor":{"value":{"error":{"code":"invalid_conversation_actor","message":"Conversation actor must be an active internal owner or admin with a live account"}}},"body":{"value":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"body","code":"invalid","message":"Invalid input"}]}}}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/conversations/{conversation_id}/notes":{"post":{"operationId":"createConversationNote","tags":["Conversations"],"summary":"Create conversation note","description":"Posts an internal note as an active workspace owner or admin. Notes can be added to open or resolved conversations without reopening them. Archived and spam conversations must be opened first. Supports Idempotency-Key; retries return the original note.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cnv_001"},"required":true,"name":"conversation_id","in":"path"},{"schema":{"type":"string","minLength":1},"required":false,"description":"Idempotency key for selected create routes.","name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateConversationNoteRequest"},"example":{"actor":{"id":"mem_002"},"body":"Open **Settings** to export your data."}}}},"responses":{"201":{"description":"Entry created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationEntryResponse"},"example":{"entry":{"id":"evt_02","conversation_id":"cnv_01","type":"note","visibility":"internal","actor":{"id":"cid_002","type":"team","name":"Jonah Reed","email":"jonah@northstar.com","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","member":{"id":"mem_002","external_id":"jonah.reed","type":"admin"}},"created_at":"2026-01-02T03:05:05.000Z","body":"Open **Settings** to export your data.","attachments":[],"edited_at":null}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Conversation or actor not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Conversation status, erased member, or idempotency conflict.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}},"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}}},"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ConversationStatusConflictErrorResponse"},{"$ref":"#/components/schemas/MemberErasedErrorResponse"},{"$ref":"#/components/schemas/IdempotencyKeyReusedErrorResponse"},{"$ref":"#/components/schemas/IdempotencyInProgressErrorResponse"}]},"example":{"error":{"code":"conversation_status_conflict","message":"Only open conversations can receive team replies"}}}}},"422":{"description":"Actor or request validation failed.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/InvalidConversationActorErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"actor":{"value":{"error":{"code":"invalid_conversation_actor","message":"Conversation actor must be an active internal owner or admin with a live account"}}},"body":{"value":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"body","code":"invalid","message":"Invalid input"}]}}}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/conversations/{conversation_id}/status":{"patch":{"operationId":"updateConversationStatus","tags":["Conversations"],"summary":"Update conversation status","description":"Sets the conversation status as the given team member. open reopens a resolved, archived, or spam conversation. resolved resolves an open one; archived and spam conversations must be opened first. Setting the status it already has is a no-op that returns the current conversation. A concurrent transition can return a status conflict.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cnv_001"},"required":true,"name":"conversation_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateConversationStatusRequest"},"example":{"status":"resolved","actor":{"id":"mem_002"}}}}},"responses":{"200":{"description":"Conversation updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationResponse"},"example":{"conversation":{"id":"cnv_001","status":"open","inbox_state":"needs_team","source":"widget","subject":"Exporting feedback","preview":"How can I export our feedback?","participants":[{"id":"cid_001","type":"customer","name":"Maya Chen","email":"maya@northstar.com","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","member":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}}],"assignee":{"id":"cid_002","type":"team","name":"Jonah Reed","email":"jonah@northstar.com","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","member":{"id":"mem_002","external_id":"jonah.reed","type":"admin","email":"jonah@northstar.com","first_name":"Jonah","last_name":"Reed","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","traits":{"monthlySpend":299,"plan":"professional","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}},"snoozed_until":null,"resolved_at":null,"last_customer_message_at":"2026-03-24T12:00:00.000Z","last_reply_at":null,"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Conversation or member not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Conversation status conflict or erased member.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ConversationStatusConflictErrorResponse"},{"$ref":"#/components/schemas/MemberErasedErrorResponse"}]},"example":{"error":{"code":"conversation_status_conflict","message":"Only open conversations can receive team replies"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Member or request validation failed.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/InvalidConversationActorErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"actor":{"value":{"error":{"code":"invalid_conversation_actor","message":"Conversation actor must be an active internal owner or admin with a live account"}}},"validation":{"value":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"status","code":"invalid","message":"Invalid input"}]}}}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/conversations/{conversation_id}/assignee":{"patch":{"operationId":"updateConversationAssignee","tags":["Conversations"],"summary":"Update conversation assignee","description":"Sets or clears the conversation assignee as the given team member. Both actor and assignee must be active workspace owners or admins. Pass null to clear the assignee. Repeating the current assignment is a no-op. Archived and spam conversations must be opened first.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cnv_001"},"required":true,"name":"conversation_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateConversationAssigneeRequest"},"example":{"assignee":{"id":"mem_002"},"actor":{"id":"mem_002"}}}}},"responses":{"200":{"description":"Conversation updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationResponse"},"example":{"conversation":{"id":"cnv_001","status":"open","inbox_state":"needs_team","source":"widget","subject":"Exporting feedback","preview":"How can I export our feedback?","participants":[{"id":"cid_001","type":"customer","name":"Maya Chen","email":"maya@northstar.com","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","member":{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}}],"assignee":{"id":"cid_002","type":"team","name":"Jonah Reed","email":"jonah@northstar.com","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","member":{"id":"mem_002","external_id":"jonah.reed","type":"admin","email":"jonah@northstar.com","first_name":"Jonah","last_name":"Reed","avatar_url":"https://assets.userjot.com/examples/jonah-reed.png","traits":{"monthlySpend":299,"plan":"professional","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}},"snoozed_until":null,"resolved_at":null,"last_customer_message_at":"2026-03-24T12:00:00.000Z","last_reply_at":null,"created_at":"2026-03-24T12:00:00.000Z","updated_at":"2026-03-25T09:30:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Conversation or member not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Conversation status conflict or erased member.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ConversationStatusConflictErrorResponse"},{"$ref":"#/components/schemas/MemberErasedErrorResponse"}]},"example":{"error":{"code":"conversation_status_conflict","message":"Only open conversations can receive team replies"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Member or request validation failed.","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/InvalidConversationActorErrorResponse"},{"$ref":"#/components/schemas/InvalidConversationAssigneeErrorResponse"},{"$ref":"#/components/schemas/ValidationErrorResponse"}]},"examples":{"actor":{"value":{"error":{"code":"invalid_conversation_actor","message":"Conversation actor must be an active internal owner or admin with a live account"}}},"assignee":{"value":{"error":{"code":"invalid_conversation_assignee","message":"Conversation assignee must be an active internal owner or admin with a live account"}}},"validation":{"value":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"assignee","code":"invalid","message":"Invalid input"}]}}}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/companies/sync":{"post":{"operationId":"syncCompany","tags":["Companies"],"summary":"Sync company","description":"Creates or updates a company by customer external_id. This upsert route always returns 200 and does not separately signal whether it created or updated the company. When creating a new company, name is required. When updating an existing company, omitted fields are left unchanged, nullable fields may be cleared with null, and traits are merged rather than replaced. logo_url ingestion is eventually consistent, so the immediate response may still include the previous logo_url.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncCompanyRequest"},"example":{"external_id":"northstar","name":"Northstar","domain":"northstar.com","logo_url":"https://assets.userjot.com/examples/northstar.png","traits":{"monthlySpend":499,"plan":"professional","industry":"SaaS","companySize":42}}}}},"responses":{"200":{"description":"Company synced successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyResponse"},"example":{"company":{"id":"cmp_001","external_id":"northstar","name":"Northstar","domain":"northstar.com","logo_url":"https://assets.userjot.com/examples/northstar.png","traits":{"monthlySpend":499,"plan":"professional","industry":"SaaS","companySize":42},"created_at":"2026-03-24T12:00:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Company identity conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyIdentityConflictErrorResponse"},"example":{"error":{"code":"company_identity_conflict","message":"external_id is already used by another company"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"external_id","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/companies":{"get":{"operationId":"listCompanies","tags":["Companies"],"summary":"List companies","description":"Lists companies with cursor pagination, free-text search, and exact-match filters for external_id and domain.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"external_id","in":"query"},{"schema":{"type":"string","minLength":1},"required":false,"name":"domain","in":"query"}],"responses":{"200":{"description":"Companies returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompaniesListResponse"},"example":{"companies":[{"id":"cmp_001","external_id":"northstar","name":"Northstar","domain":"northstar.com","logo_url":"https://assets.userjot.com/examples/northstar.png","traits":{"monthlySpend":499,"plan":"professional","industry":"SaaS","companySize":42},"created_at":"2026-03-24T12:00:00.000Z"}],"next_cursor":"cursor_2"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"limit","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/companies/lookup":{"get":{"operationId":"lookupCompany","tags":["Companies"],"summary":"Lookup company","description":"Resolves a company by customer external_id.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"external_id","in":"query"}],"responses":{"200":{"description":"Company returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyResponse"},"example":{"company":{"id":"cmp_001","external_id":"northstar","name":"Northstar","domain":"northstar.com","logo_url":"https://assets.userjot.com/examples/northstar.png","traits":{"monthlySpend":499,"plan":"professional","industry":"SaaS","companySize":42},"created_at":"2026-03-24T12:00:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Company not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"external_id","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/companies/{company_id}":{"get":{"operationId":"getCompany","tags":["Companies"],"summary":"Get company","description":"Retrieves a single company by id.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cmp_001"},"required":true,"name":"company_id","in":"path"}],"responses":{"200":{"description":"Company returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyResponse"},"example":{"company":{"id":"cmp_001","external_id":"northstar","name":"Northstar","domain":"northstar.com","logo_url":"https://assets.userjot.com/examples/northstar.png","traits":{"monthlySpend":499,"plan":"professional","industry":"SaaS","companySize":42},"created_at":"2026-03-24T12:00:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Company not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"patch":{"operationId":"updateCompany","tags":["Companies"],"summary":"Update company","description":"Partially updates company fields, external_id, and traits by id. Traits are merged rather than replaced. logo_url ingestion is eventually consistent, so the immediate response may still include the previous logo_url.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cmp_001"},"required":true,"name":"company_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCompanyRequest"},"example":{"external_id":"northstar-updated","name":"Northstar","domain":"northstar.com","logo_url":"https://assets.userjot.com/examples/northstar.png","traits":{"monthlySpend":499,"plan":"professional","industry":"SaaS","companySize":42}}}}},"responses":{"200":{"description":"Company updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyResponse"},"example":{"company":{"id":"cmp_001","external_id":"northstar","name":"Northstar","domain":"northstar.com","logo_url":"https://assets.userjot.com/examples/northstar.png","traits":{"monthlySpend":499,"plan":"professional","industry":"SaaS","companySize":42},"created_at":"2026-03-24T12:00:00.000Z"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Company not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"Company identity conflict.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyIdentityConflictErrorResponse"},"example":{"error":{"code":"company_identity_conflict","message":"external_id is already used by another company"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"logo_url","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/companies/{company_id}/members":{"get":{"operationId":"listCompanyMembers","tags":["Company Members"],"summary":"List company members","description":"Lists listable members linked to a company with cursor pagination ordered newest-first by association creation time. Guest, anonymous, and erased members are excluded.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cmp_001"},"required":true,"name":"company_id","in":"path"},{"schema":{"$ref":"#/components/schemas/Cursor"},"required":false,"description":"Opaque pagination cursor.","name":"cursor","in":"query"},{"schema":{"type":"integer","exclusiveMinimum":0,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Company members returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyMembersResponse"},"example":{"members":[{"id":"mem_001","external_id":"maya.chen","type":"user","email":"maya@northstar.com","first_name":"Maya","last_name":"Chen","avatar_url":"https://assets.userjot.com/examples/maya-chen.png","traits":{"monthlySpend":49,"plan":"starter","isTrialing":false},"created_at":"2026-03-24T12:00:00.000Z"}],"next_cursor":"cursor_2"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Company not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"limit","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}},"post":{"operationId":"addCompanyMember","tags":["Company Members"],"summary":"Add company member","description":"Adds an existing listable member to a company. This route manages the relationship only and does not implicitly create members.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cmp_001"},"required":true,"name":"company_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCompanyMemberRequest"},"example":{"member":{"external_id":"maya.chen"}}}}},"responses":{"200":{"description":"Company member added successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"},"example":{"ok":true}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Company or member was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"409":{"description":"The referenced member has been erased.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberErasedErrorResponse"}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"},"example":{"error":{"code":"validation_error","message":"Request validation failed","details":{"issues":[{"path":"member","code":"invalid","message":"Invalid input"}]}}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}},"/companies/{company_id}/members/{member_id}":{"delete":{"operationId":"deleteCompanyMember","tags":["Company Members"],"summary":"Delete company member","description":"Removes a member-company association only. This route does not delete the member or the company.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"example":"cmp_001"},"required":true,"name":"company_id","in":"path"},{"schema":{"type":"string","minLength":1,"example":"mem_001"},"required":true,"name":"member_id","in":"path"}],"responses":{"204":{"description":"Company member removed successfully.","headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"401":{"description":"API token is missing, invalid, or inactive.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidApiTokenErrorResponse"},"example":{"error":{"code":"invalid_api_token","message":"Invalid API token"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"404":{"description":"Company or member was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFoundErrorResponse"},"example":{"error":{"code":"not_found","message":"Not found"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}},"429":{"description":"Rate limit exceeded. Retry after the delay indicated by the Retry-After header.","headers":{"Retry-After":{"description":"Returned when the client should wait before retrying the same request.","schema":{"type":"string","pattern":"^\\d+$"}},"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitedErrorResponse"},"example":{"error":{"code":"rate_limited","message":"Too many requests","details":{"retry_after_seconds":30}}}}}},"500":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalErrorResponse"},"example":{"error":{"code":"internal_error","message":"Internal server error"}}}},"headers":{"X-Request-Id":{"description":"Returned with every public API response.","schema":{"type":"string","minLength":1}}}}}}}},"x-tagGroups":[{"name":"Boards","tags":["Boards"]},{"name":"Requests","tags":["Requests","Request Workflow","Request Comments","Request Comment Votes","Request Comment Attachments","Request Votes","Request Subscriptions","Request Attachments","Request Tags"]},{"name":"Changelogs","tags":["Changelogs","Changelog Authors","Changelog Requests","Changelog Tags"]},{"name":"Members & Companies","tags":["Members","Companies","Company Members"]},{"name":"Assets","tags":["Assets"]},{"name":"Conversations","tags":["Conversations"]}]}