GitHub API
These endpoints work with the organization’s GitHub integration:
the GitHub accounts where the Probara GitHub App is installed. Installing the app, disconnecting an
account, changing a project’s repositories and its pull request comments setting need a signed-in
session; with an API token they answer 403 forbidden. Everything else works with an
API token and through the MCP tools.
Every endpoint needs the Pro or Enterprise plan; on other plans it answers 403 forbidden. A
{projectId} is the project code, such as SHOP. Repositories are written owner/name.
Repositories a project may use
Section titled “Repositories a project may use”A project offers the repositories of its mapping. When the mapping is empty, it offers every
repository the organization’s installations can see. Every endpoint below that takes a
repository checks it against that rule.
| Method and path | What it does |
|---|---|
GET /api/v1/projects/{projectId}/integrations/github/repositories | The project’s mapping: items with connectionUlid, repositoryId, repositoryFullName, isDefault. Empty means no mapping. |
GET /api/v1/projects/{projectId}/integrations/github/linkable-repositories | The repositories the project offers now, mapping or not: connectionUlid, repositoryId, fullName, isDefault. |
PUT /api/v1/projects/{projectId}/integrations/github/repositories | Replaces the mapping with { "repositories": [{ "connectionUlid", "repositoryId", "isDefault" }] }. Session only, integrations.manage. |
GET /api/v1/projects/{projectId}/integrations/github/settings | { "pullRequestComments": "on_failure" }: when closed GitHub Actions runs comment on their pull request: always, on_failure or off. |
PUT /api/v1/projects/{projectId}/integrations/github/settings | Sets pullRequestComments to always, on_failure or off. Session only, integrations.manage. |
Link issues
Section titled “Link issues”The same four endpoints exist for test cases, runs and defects. {entity} is
test-cases/{caseUlid}, runs/{runUlid} or defects/{defectUlid}.
| Method and path | What it does |
|---|---|
GET /api/v1/{entity}/github-issues | Lists the entity’s links. |
POST /api/v1/{entity}/github-issues/link | Links an issue. Answers 201 with the link. |
POST /api/v1/{entity}/github-issues/{linkUlid}/refresh | Reads the issue from GitHub again and answers the updated link. |
DELETE /api/v1/{entity}/github-issues/{linkUlid} | Removes the link. The issue stays in GitHub. Answers 204. |
{ "connectionUlid": "01J9Z3K4M5N6P7Q8R9S0T1V2W3", "repository": "acme/shop", "issueNumber": 42, "linkKind": "requirement"}linkKind is requirement or defect, and defaults to requirement on a test case and defect
on a run or a defect. Only defect links on a defect sync the defect’s status with the issue;
requirement links on test cases are what GitHub traceability reports count as coverage.
A link carries repositoryFullName, issueNumber, linkKind, and the issue’s title, state
(open or closed), stateReason, labels, authorLogin, htmlUrl and issueUpdatedAt as
GitHub last answered, with syncedAt, when Probara last read them. These cached fields are
answered even while GitHub is unreachable, and refresh on every change GitHub reports.
Reading links needs access to the entity. Changing them needs test-cases.write on a test case,
runs.execute on a run and defects.write on a defect.
Search a repository’s issues
Section titled “Search a repository’s issues”GET /api/v1/projects/{projectId}/integrations/github/issues/search?connectionUlid=…&repository=acme/shop&q=checkout
searches the repository’s issues by words of the title, or reads one by number with q=42 or
q=#42. q holds up to 200 characters and is searched as plain text: it cannot add GitHub search
qualifiers. It answers up to 20 issues, never pull requests.
Create an issue from a defect
Section titled “Create an issue from a defect”| Method and path | What it does |
|---|---|
GET /api/v1/defects/{defectUlid}/github-issues/draft | The prefilled title and body. Add ?resultUlid= (a result linked to the defect) to prefill from that result. |
GET /api/v1/projects/{projectId}/integrations/github/labels | The labels of a repository (connectionUlid, repository), with name, color and description. |
POST /api/v1/defects/{defectUlid}/github-issues | Creates the issue and links it to the defect as defect. |
{ "connectionUlid": "01J9Z3K4M5N6P7Q8R9S0T1V2W3", "repository": "acme/shop", "resultUlid": "01J9Z3M7Q2R4S6T8V0W2X4Y6Z8", "labels": ["bug"]}title (up to 256 characters) and body (GitHub Markdown, up to 65,536 characters) are optional:
without them, the draft is used: its body is the defect description as Markdown, with each image at its stored asset URL. labels holds up to 20 names of the repository. It needs
defects.write.
The create is sent to GitHub once. It answers 201 with the new link, or 200 when a retry finds
the issue an earlier request opened. When GitHub’s answer is lost, the request answers
409 github_issue_creation_unconfirmed with Retry-After: retry after that delay, and Probara
looks for the issue before opening another one.
Launch a workflow
Section titled “Launch a workflow”| Method and path | What it does |
|---|---|
GET /api/v1/projects/{projectId}/integrations/github/workflows | The repository’s active workflows (connectionUlid, repository): id, name, path. |
GET /api/v1/projects/{projectId}/integrations/github/branches | The repository’s branches, up to 500. |
POST /api/v1/projects/{projectId}/integrations/github/launches | Creates an automated run and starts the workflow on a branch. |
{ "connectionUlid": "01J9Z3K4M5N6P7Q8R9S0T1V2W3", "repository": "acme/shop", "ref": "main", "workflowId": "probara-e2e.yml", "runName": "Nightly E2E"}workflowId is an id from the workflows list or the workflow’s file name. runName defaults to the
workflow name and the branch. inputs adds up to 24 more workflow_dispatch string inputs;
Probara always sends the run’s ULID as probara_run_id. The workflow contract is in
Running tests with GitHub Actions.
It needs runs.execute, and accepts an Idempotency-Key.
201: GitHub accepted the dispatch. The body is the run, withgithubBuild.launchStatusdispatched.202: GitHub’s answer was lost. The run is kept withlaunchStatusunconfirmed; its build fills in if the workflow did start.- A refusal (
github_workflow_*,github_ref_not_found) leaves no run behind.
GET /api/v1/runs/{runUlid} returns githubBuild for a launched run (null for any other run):
launchStatus, repository, ref, workflowName, htmlUrl, status, conclusion, runAttempt,
startedAt and completedAt. The build fields stay null until GitHub reports the workflow run.
Probara never closes the run from the build: the workflow’s final job does.
Traceability sources
Section titled “Traceability sources”GitHub connections appear in GET /api/v1/projects/{projectId}/traceability/sources with
provider: "github". The repositories, labels and milestones a report can use are under
/sources/{connectionUlid}/repositories, /labels?repository= and /milestones?repository=. See
the traceability reports API.
Errors
Section titled “Errors”Every error uses the standard error envelope.
| Status | Code | When |
|---|---|---|
403 | forbidden | The plan does not include integrations, the caller lacks the permission, or a session-only route got a token. |
403 | github_repository_not_mapped | The project’s mapping leaves the repository out. |
404 | github_issue_not_found | The repository has no issue with that number. |
404 | github_workflow_not_found | The repository has no such workflow. |
409 | github_issue_already_linked | The entity already links that issue. |
409 | github_connection_stale | The installation was suspended or uninstalled in GitHub. |
409 | github_issue_creation_in_progress | Another request is creating this defect’s issue in that repository. |
409 | github_issue_creation_unconfirmed | GitHub’s answer to an earlier create was lost. Retry after Retry-After. |
422 | github_repository_not_visible | The installation cannot see the repository. |
422 | github_issue_is_pull_request | The number is a pull request. |
422 | github_issues_disabled | Issues are turned off in the repository. |
422 | github_issue_rejected | GitHub refused the new issue, for example for an unknown label. |
422 | github_workflow_not_dispatchable | The workflow is disabled or has no workflow_dispatch trigger. |
422 | github_ref_not_found | The repository has no such branch. |
422 | github_workflow_missing_run_input | The workflow does not declare the probara_run_id input under workflow_dispatch. |
422 | github_workflow_dispatch_failed | GitHub refused the dispatch, for example for an undeclared input. details.message holds GitHub’s reason. |
422 | validation_failed | The body or a query parameter is malformed. |
429 | too_many_requests | The organization’s GitHub request limit is reached. Retry-After says when to retry. |
503 | github_app_not_configured | The GitHub App is not set up in this environment. |
503 | github_unavailable | GitHub cannot be reached right now. |