A GitHub link attaches a commit or pull request reference to a ticket so people can jump from the ticket to the code. SAQ stores the reference only: it has no GitHub App, does not read the repository, does not react to pushes or merges, and never contacts GitHub. A CI job, a deploy script, or an assistant adds the link; nothing happens automatically.
Before you start
You need a token with the write scope, and the token's owner must be allowed to edit the ticket (an Owner or Admin, a full member of the ticket's project, or any workspace user for an Inbox ticket).
Fields
| Field | Rule |
|---|---|
repo |
owner/name, letters, digits, ., _, - only. Error reason repo_format |
url |
An https://github.com/{owner}/{name}/… address, at most 500 characters, and it must start with the same repository as repo (case-insensitive). Error reason github_url |
sha |
Optional. 7–40 hexadecimal characters; stored lower-case. When given, url must contain /commit/{sha}. Error reason sha_format |
pr |
Optional. A positive integer; when given, url must contain /pull/{pr}. Error reason pr_format |
At least one of sha or pr is required (reason sha_or_pr_required). Validation failures answer 400 invalid with details.reason and details.field.
Add a link
curl -X POST "https://saq.no/api/w/acme/tickets/ACME-184/github" \
-H "Authorization: Bearer saq_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"repo": "acme/website",
"pr": 512,
"url": "https://github.com/acme/website/pull/512"
}'
Response (201):
{
"id": "01924c3e-0000-7000-8000-000000000020",
"repo": "acme/website",
"sha": null,
"pr": 512,
"url": "https://github.com/acme/website/pull/512",
"createdAt": "2026-09-19T10:15:00.000Z"
}
A commit link uses sha instead: { "repo": "acme/website", "sha": "9fceb02d", "url": "https://github.com/acme/website/commit/9fceb02d" }.
Other ways to add the same link:
- MCP tool
link_githubwithticket,repo,url, andshaorpr. See Connect an MCP client. - On the ticket page, paste the commit or pull request URL under GitHub and select Add.
Each addition writes a github_linked event on the ticket's timeline and counts as ticket activity.
Remove a link
curl -X DELETE "https://saq.no/api/w/acme/tickets/ACME-184/github/01924c3e-0000-7000-8000-000000000020" \
-H "Authorization: Bearer saq_YOUR_TOKEN"
Answers 200 { "ok": true } and writes a github_unlinked event. An unknown link id answers 404 not_found.
Read links
- A ticket's links are in the
githubarray ofGET /api/w/acme/tickets/ACME-184and of the MCP toolget_ticket. - The MCP context pack has a
githubsection listing links on the tickets it returns. - The workspace-wide list under Settings → Channels → GitHub (
GET /api/w/acme/github/links) is browser-only; it is not open to API tokens.
Common problems
- "URL must be an https://github.com/… address" although the URL looks right: the repository in
urldiffers fromrepo, or thesha/prdoes not appear in the URL as/commit/{sha}or/pull/{pr}. 404 not_foundon the ticket: the token's owner cannot see it, or the token is project-scoped to other projects.403 forbidden: the token lacks the write scope, or the owner cannot edit the ticket.