Skip to content

Conventions

This page documents the cross-cutting rules that apply to the public API.

Examples throughout the API docs use sample IDs, keys, and timestamps to show shape and type. Treat field names, field presence, accepted parameters, and status codes as authoritative.

All /v1 endpoints require:

Authorization: Bearer <access-token>
  • OAuth endpoints require application/x-www-form-urlencoded
  • /v1 write endpoints accept application/json
  • JSON property names are camelCase, except OAuth responses which use protocol-standard snake_case fields such as access_token

Collection endpoints return:

{
"results": [],
"pagination": {
"pageSize": 100,
"cursor": "",
"nextCursor": "",
"hasMore": false,
"returnedCount": 0,
"totalCount": 0
}
}

Detail endpoints return the resource directly, not wrapped in a data object.

Most collection endpoints accept:

ParameterTypeNotes
cursorstringOpaque cursor from the previous page
page_sizeintegerDefault 100, minimum 1, maximum 100
  • Missing cursor means the first page
  • Invalid cursor returns 400 invalid_request
  • Invalid page_size returns 400 invalid_request
  • nextCursor is empty when there is no next page

Errors under /v1 use this shape:

{
"code": "validation_failed",
"message": "The issue write request was not valid.",
"errors": [
{
"field": "title",
"code": "required",
"message": "A title is required."
}
]
}

Field-level entries under errors vary by operation. The structure is stable even when the exact field codes differ.

CodeTypical statusMeaning
unauthorized401Missing bearer token
invalid_token401Invalid or expired token
insufficient_scope403Missing required scope
forbidden403Authenticated caller cannot access the target resource
not_found404Resource not found or not visible
invalid_request400Invalid query or malformed request semantics
validation_failed400Invalid JSON payload
conflict409Request conflicts with existing data
rate_limited429API rate limit exceeded
internal_error500Unexpected server error
SurfaceDefault limit
/oauth30 requests per 60 seconds
/v1600 requests per 60 seconds

Rate-limited /v1 responses may include Retry-After.

Example:

{
"code": "rate_limited",
"message": "The rate limit has been exceeded. Retry after 12 seconds."
}
  • Issue and project description fields are plain text in the public API
  • Issue and project write requests accept plain text description
  • Issue comment write requests accept plain text body
  • Issue comment responses return body as a structured rich-text document

Example rich-text comment body:

{
"schemaVersion": 1,
"content": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "First line"
},
{
"type": "hardBreak"
},
{
"type": "text",
"text": "Second line"
}
]
}
]
}
}

Attachment content and preview endpoints do not return the file body directly. They return 302 Found redirects to signed URLs.

Several nested issue objects expose both a specialized ID field and a generic id alias.

Example:

{
"statusId": "iss-status_open",
"id": "iss-status_open",
"name": "Open"
}

This pattern applies to nested issue status, issue project, issue label, and issue link objects.

  • DateTimeOffset values are ISO 8601 timestamps such as 2025-02-24T16:45:00Z
  • DateOnly values are YYYY-MM-DD

Several response fields serialize as numeric codes.

ValueMeaning
0None
1Urgent
2High
3Medium
4Low
ValueMeaning
0Human
1Service
2Agent
ValueMeaning
1Owner
2Admin
3Member
4Guest
ValueMeaning
1Invited
2Active
3Suspended
4Removed
ValueMeaning
1GitHub
2Azure DevOps
ValueMeaning
0Unsupported
1Image
2Pdf
3Video
4Audio
5Text
6Code
7Word
8Excel
ValueMeaning
1Automated
2Journal
3Update
4Handover
ValueMeaning
1Human
2Agent
3System
ValueMeaning
1Active
2WaitingOnAgent
3WaitingOnUser
4Closed