GitHub links

How a ticket stores a reference to a GitHub commit or pull request, the validation rules, and the fact that SAQ never contacts GitHub.

Written for
integration-developer
Roles
Requires
API token with the write scope; Permission to edit the ticket
Feature
tickets

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.

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_github with ticket, repo, url, and sha or pr. 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.

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.

  • A ticket's links are in the github array of GET /api/w/acme/tickets/ACME-184 and of the MCP tool get_ticket.
  • The MCP context pack has a github section 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 url differs from repo, or the sha/pr does not appear in the URL as /commit/{sha} or /pull/{pr}.
  • 404 not_found on 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.