REST API reference
The REST API is generated from the Tiden gRPC API through grpc-gateway. Public automation should use API tokens and the endpoints listed as public.
Base URL
https://app.tiden.ai
Authentication header
Authorization: Bearer <token>
Public API endpoints
These endpoints are intended for API tokens, CLI, MCP, CI, and customer automation.
Auth, workspace, and product
| Method | Path | Purpose |
|---|---|---|
GET | /v1/auth/me | Current user for the token |
PUT | /v1/auth/onboarding | Update onboarding state |
GET | /v1/workspaces | List workspaces |
POST | /v1/workspaces/{workspace_id}/products | Create product |
GET | /v1/workspaces/{workspace_id}/products | List products |
POST | /v1/products/{product_id}/setup:verify | Verify product setup state |
Specs
In the API, a spec is the requirement resource. Paths, path parameters such as
requirement_id, and JSON fields such as requirementId keep that name.
| Method | Path | Purpose |
|---|---|---|
POST | /v1/products/{product_id}/requirements | Create spec |
GET | /v1/products/{product_id}/requirements | List specs |
GET | /v1/requirements/{id} | Get spec |
PUT | /v1/requirements/{id} | Update spec |
DELETE | /v1/requirements/{id} | Delete spec |
Tests
| Method | Path | Purpose |
|---|---|---|
POST | /v1/products/{product_id}/tests | Create suite or case |
PUT | /v1/tests/{id} | Update test |
GET | /v1/products/{product_id}/tests | List tests |
GET | /v1/tests/{id} | Get test |
DELETE | /v1/tests/{id} | Delete test |
POST | /v1/tests/{test_id}/links | Link test to spec or propose branch link |
DELETE | /v1/tests/{test_id}/links/{requirement_id} | Unlink test and spec |
GET | /v1/tests/{test_id}/links | List test links |
GET | /v1/branches/{branch_id}/link-proposals | List branch link proposals |
POST | /v1/branches/{branch_id}/link-proposals:review | Review branch link proposals |
POST | /v1/products/{product_id}/tests:ingest | Ingest reporter draft |
Branches and components
| Method | Path | Purpose |
|---|---|---|
POST | /v1/products/{product_id}/branches | Create branch |
GET | /v1/products/{product_id}/branches | List branches |
GET | /v1/branches/{id} | Get branch |
PATCH | /v1/branches/{id} | Update branch |
POST | /v1/branches/{id}:close | Close branch |
DELETE | /v1/branches/{id} | Delete branch |
GET | /v1/branches/{id}/merge-preview | Preview merge |
POST | /v1/branches/{id}/merge | Merge branch |
GET | /v1/branches/{id}/merged-changes | List what a merged branch put into main |
POST | /v1/branches/{branch_id}/intent-hold | Hold or release the automatic merge of an intent branch |
POST | /v1/products/{product_id}/components | Create component |
GET | /v1/products/{product_id}/components | List components |
GET /v1/branches/{id}/merge-preview returns the changes a merge would apply
to main. Its fields, item shapes, and schema version are in
Merge preview response.
PATCH /v1/branches/{id} changes a branch's description on any status.
POST /v1/branches/{id}:close ends a branch and keeps everything on it; it
answers BRANCH_CLOSE_DENIED for main and for an automatic branch, and
BRANCH_NOT_OPEN for a merged one. A closed branch answers BRANCH_NOT_OPEN
to writes, code links, and holds, and the branch object carries closedAt and
closedByName. See Closed branches.
POST /v1/branches/{id}/merge accepts an optional expectPreviewDigest: the
previewDigest of the merge preview you reviewed. When the branch changed
after that preview, the merge answers 409 Conflict with
MERGE_PREVIEW_STALE and merges nothing. Run the merge preview again and use
its digest. See
Merge only the reviewed preview.
GET /v1/branches/{id}/merged-changes lists the changes a merged branch put
into main. It answers for merged branches only. Page it with
pagination.page_size (default 50, at most 200) and pagination.page_token.
It does not return the actor's email.
Environments and releases
| Method | Path | Purpose |
|---|---|---|
POST | /v1/products/{product_id}/environments | Create environment |
GET | /v1/products/{product_id}/environments | List environments |
GET | /v1/environments/{id} | Get environment |
DELETE | /v1/environments/{id} | Delete environment |
POST | /v1/products/{product_id}/releases | Create or update release |
GET | /v1/products/{product_id}/releases | List releases |
GET | /v1/releases/{id} | Get release |
POST | /v1/releases/{id}/quality-gate:capture | Capture the release's Quality Gate again |
Creating a release accepts an optional buildSha: the full 40- or
64-character commit SHA the release was built from. A short or non-hexadecimal
value is refused with INVALID_BUILD_SHA. A release's gate is then captured
from that commit's test results; see
Release captures. The capture
call takes an optional {"buildSha": "…"} body and returns the release, its
current verdict, pending and appended. Reading the verdict or traceability
of a release that is still pending answers QG_CAPTURE_PENDING.
Quality gates
| Method | Path | Purpose |
|---|---|---|
POST | /v1/products/{product_id}/quality-gate:compute | Compute verdict |
GET | /v1/products/{product_id}/quality-gate | Get latest verdict |
GET | /v1/products/{product_id}/quality-gate/traceability | Get traceability matrix |
POST | /v1/products/{product_id}/quality-gate:accept-risk | Accept risk |
POST | /v1/products/{product_id}/quality-gate:approve-risk | Approve risk |
Agents
| Method | Path | Purpose |
|---|---|---|
GET | /v1/agent-types | List agent types |
GET | /v1/products/{product_id}/agent-configs | List agent configs |
GET | /v1/agent-configs/{id} | Get agent config |
POST | /v1/products/{product_id}/agent-configs | Create agent config |
DELETE | /v1/agent-configs/{id} | Delete agent config |
POST | /v1/agent-configs/{agent_config_id}/runs | Start agent run |
POST | /v1/agent-runs/{id}:cancel | Cancel agent run |
GET | /v1/agent-runs/{id} | Get agent run |
GET | /v1/agent-configs/{agent_config_id}/runs | List runs |
GET | /v1/agent-runs/{run_id}/events | List run events |
GET | /v1/agent-runs/{run_id}/events:stream | Stream run events |
Agent retrieval and intent
| Method | Path | Purpose |
|---|---|---|
GET | /v1/products/{product_id}/coverage-gaps | Get coverage gaps |
GET | /v1/products/{product_id}/requirements/{requirement_id}/test-context | Get test generation context |
POST | /v1/products/{product_id}/test-generation-context:prepare | Prepare test generation context |
POST | /v1/products/{product_id}/intent:distill | Distill intent into branch |
Issues
Error tracking reads and status changes are available to API tokens, so the CLI, the MCP server, CI, and coding agents can triage issues without a browser session.
| Method | Path | Purpose |
|---|---|---|
GET | /v1/products/{product_id}/issues | List issues, newest activity first |
GET | /v1/issues/{id} | Get an issue with its latest occurrence |
GET | /v1/issues/{id}/events | List an issue's occurrences |
GET | /v1/issues/{id}/events/{event_id} | Get one occurrence with symbolicated frames |
GET | /v1/issues/{id}/stats | Occurrence counts over time and per environment |
GET | /v1/releases/{release_id}/issues | Issues first seen in a release |
POST | /v1/issues/{id}:setStatus | Set one issue's status |
POST | /v1/products/{product_id}/issues:bulkSetStatus | Set the same status on many issues |
GET | /v1/products/{product_id}/issues/{issue_id}/fix-context | Everything needed to fix one issue, in one call |
Notes:
GET /v1/products/{product_id}/issuesfilters onstatus(unresolved,resolved,ignored, or empty for all),environment_id,release_id,component_id, repeatedplatforms, and a trailingperiodwindow (3m,1h,12h,1d,7d,30d). Sort withsort(last_seen,first_seen,times_seen) and page with the opaque cursor inpagination.page_token. Issues are not filtered by level: a request that sendslevelsfails with400 Bad Request.- An issue itself has no environment — environment lives on its occurrences.
Use
GET /v1/issues/{id}/statsto learn where an issue is actually happening. GET /v1/issues/{id}symbolicates only the latest occurrence. When the occurrence that matters is not the latest one, fetch it directly withGET /v1/issues/{id}/events/{event_id}.event_idin the occurrence path is the occurrence's Tiden id, not theevent_idthe SDK generated.- Status changes are recorded with the actor that made them and are reversible.
fix-contextreturns the issue, its symbolicated frames, the repository files those frames implicate, the per-environment split, the attributed component, and, for each spec those files implement, whether a test already covers it (verified,not_run, orno_test). It acceptsbranchandmax_frames, clears the raw event payload, and names anything it dropped intruncation_signals. Prefer it over stitching the reads above together.
Source map upload
| Method | Path | Purpose |
|---|---|---|
POST | /v1/products/{product_id}/sourcemaps | Create source map upload |
POST | /v1/sourcemaps/{id}:confirm | Confirm source map upload |
Web-only endpoint groups
These are primarily for the Tiden web app and browser sessions:
- Signup, login, refresh, logout, profile, password, avatar, MFA, and passkeys.
- API token create/list/revoke.
- Organization members, invites, roles, statuses, workspace scopes, and invite links.
- Workspace create/update/delete, members, invites, and invite links.
- Product get/update/delete and product setup read.
- Component get/update/delete.
- Environment update.
- Spec/test move, history, and restore.
- Attachment upload/download.
- Credential create/list/delete/test.
- Billing overview, checkout, portal, and pricing.
- Issue DSN key management, inbound filters, the issue overview aggregates that back UI tiles (counts, stats, facets), and source map list/delete.
- Quality gate overview history and mark-seen.
- Agent config update, memory, triggers, and artifacts.
Error tracking ingest endpoint
SDK event ingest is not a proto REST endpoint. It is a separate DSN-authenticated HTTP surface:
POST /api/{product_id}/envelope/?tiden_key=<publicKey>
POST /api/{product_id}/store/?tiden_key=<publicKey>
Use Custom ingest only when an official SDK is not available.