REST API #

View this page as Markdown

The REST API is how a program with no MCP client, such as a script or a CI job, works a tzTrack space over HTTPS. It takes the same token as the MCP server at https://tztrack.ai/mcp, admits you at the same level, and applies the same rules. It also makes acts the MCP server's tools do not, such as land, check, and configure. Read this page when your caller speaks plain HTTP rather than MCP.

Requests and answers #

Every call is a POST to https://tztrack.turnzero.ai/v1/<act>, such as /v1/list. The body is one JSON object: the act's request, as the table in the section The acts lists it, with space beside it. An empty body counts as {}.

Leave space out where your account owns or is a member of one space: that space is the default. Where it holds several, name one by its id. The project's setting file holds the id a project works in.

A body is at most 65,536 bytes. submit and comment carry images, so their bound is 3,145,728 bytes.

A call that works answers 200 and a JSON object with three members:

  • space, the id of the space the act worked;
  • act, the act's name;
  • result, the act's own answer, as the table lists it.

A call that fails answers an error status and a JSON object with two members: error, the refusal's name, and detail, one sentence on what to do next. Branch on error, never on detail, since the sentence can change. A refused call changes nothing.

The token #

Send a tzTrack token in the authorization header as Bearer <token>. It is the token Turn Zero signs for tzTrack, the same token an AI tool holds after you sign in.

A script or a CI job gets its token one of two ways. It can mint one with the action mint_token, the grant tztrack, and a label you give, from your account's own signed-in session on Turn Zero Cloud. The mint answers a token claim line, which you run in a terminal of your own, so the value never passes through the chat. Mint a token gives the steps. Or it can sign in by itself with a code you allow in a browser, the device sign-in, naming https://tztrack.ai/mcp as the resource.

Sign in from a script gives every answer of the device sign-in. The Quick start gives both ways step by step. Keep the token as a secret, as you keep a password. The REST API verifies it as it verifies the token an AI tool holds after sign-in.

Any other credential is refused credential_refused, a token for another Turn Zero product among them. A call with no authorization header is refused credential_required. Both answers carry a www-authenticate header naming where the sign-in starts.

In a space of your own you hold the owner's level, and every act works. In a space shared with you, you hold the level its owner gave you: report, contribute, or owner. An act past your level is refused grant_required.

The acts #

The table names each act, the lowest level that makes it, the members its request takes, and what result holds. key, where an act takes it, is your own idempotency key: repeat a write with the same key and it is made once. A write is recorded under your account and your token's label, whatever actor a body names.

A member that names an issue takes its number, as 12 or "#12", or its id, as the MCP tools take it. Those members are issue, a settle's target, a relate's target other than an arising_from reference, and follow's repeat_of.

Act Level Request result
submit report origin, kind, title; where you have them, text, impact, workaround, proposed_resolution, seen_in, evidence, evidence_basis, restricted, component, problem_key, attachments, amends, withdraws, key; from contribute, requirements, labels, and priority, each refused grant_required below it report, issue, outcome, candidates, masked, personal_removed
follow report report, repeat_of, key report, issue, outcome
list report the filters state, outcome, kind, component, path, requirement, label, priority, level, alarm, origin, waiting_for, claimed_by, plan, reporter, proposed, related, since; order, limit, cursor issues, cursor
search report query; the filters state, kind, component; limit, cursor issues, cursor
read report issue issue, reports, links, history, comments, relations, landings, checks, proposals
attachment contribute id, one image's id as a report or a comment lists it type, the image's media type, and bytes, its bytes in base64url
update contribute issue, fields, key issue, mentioned
comment contribute issue, text, attachments, key comment, issue, mentioned
relate contribute issue, type, target, withdraw, key issue, relation
next contribute role, branch, component, paths, plan, key issue, check, secret, packet
give_back contribute issue, check, secret, reason, key issue
wait contribute issue, waiting_for, resolution, key issue
cache contribute since for a refresh link, expires_at, space, since, count, numbers, gone
land owner issue, commit, trailer, test, proof, remainder, component, key landing, issue
deploy owner line, version, order, commit, environment, live, withdrawn, key build
ship owner build, landings, key build, shipped
check owner check, covers, result, builds, cause, component, evidence, withdraw, key check, issue, outcome
settle owner issue, outcome, target, resolution, fixed_in, key issue, related_open
reopen owner issue, key issue
unmerge owner issue, key issue
configure owner components, lines, credential_forms, personal_forms, machinery, main_paths, constants configuration
export owner limit, cursor issues, comments, signals, asks, landings, builds, checks, cursor
count owner the filters of list, exclude_label, group_by total, groups
rates owner since, until, grain, component, kind, label, exclude_label since, until, grain, steps, time_to_close
read_space owner nothing space, counts, configuration, sampled_merges, pass_runs

The form of each member is the contract's: Issue Tracking gives every member's type, bounds, and meaning, and every answer member's.

What differs from the contract #

A few members are set for you, and a few are bounded, each refused where the body passes the bound.

Set for you, whatever the body says:

  • A write's actor is your account and your token's label, written as an agent.
  • A filing's evidence_basis is claimed where the body names none.
  • Below the owner's level, a filing's origin is field.

Refused where the body passes the bound:

  • An evidence_basis other than claimed is refused invalid_request. So is a seen_in entry other than { line, version, environment } with a repository commit as its version.
  • A body that names relayed_level is refused invalid_request. Your level in the space decides which restricted issues your filings join.
  • A waiting_for of person:<account> names the space's owner or one of its members, and any other account is refused invalid_request.
  • Below the owner's level, an update that lowers restricted or names alarm is refused grant_required. A relate of the type arising_from whose target is an issue's number, such as #7, is refused invalid_request there too.
  • configure takes the members the table lists. Among constants it takes report_text_retention_days, lift_reports, lift_window_days, lift_account_max, and rank_trial_weight, and refuses every other, model_budget among them.
  • A configure that sets machinery.passes to true on a space with no model budget sets the budget to 200 in the same call. A budget already set stands.

Every other act of the contract, such as mint, revoke, or delete_space, is refused grant_required, whatever your level. Turn Zero Cloud makes those acts for you, and sharing a space and creating one are its own: the MCP server's share and create_issue_space tools carry them.

Refusals #

A refusal names itself in error. Refusals gives each one's status, cause, and remedy, from credential_required to rate_limited.

Two answers are no refusal of an act. A path that names no act answers 404 not_found, whatever the method: check the act's spelling against the table. A request to an act's path that is no POST answers 405 method_not_allowed, with an allow header naming POST.

An example #

This lists the open issues of your one space with curl, the token in the variable TZTRACK_TOKEN:

curl -s -X POST https://tztrack.turnzero.ai/v1/list -H "authorization: Bearer $TZTRACK_TOKEN" -H "content-type: application/json" -d '{"state": "open", "limit": 20}'

The answer holds the space's id as space, list as act, and the page of issues with its cursor as result. To raise an issue in a named space:

curl -s -X POST https://tztrack.turnzero.ai/v1/submit -H "authorization: Bearer $TZTRACK_TOKEN" -H "content-type: application/json" -d '{"space": "<id>", "origin": "workspace", "kind": "bug", "title": "The nightly build fails on the login test", "text": "Seen on three runs since Monday."}'

Any HTTP client works the same way: a POST, the authorization header, and one JSON object.

  • The tools lists the MCP server's tools, which make some of the same acts, under the same rules.
  • Refusals lists every refusal with its remedy.
  • Sharing a space explains the levels a member works at.
  • The setting file gives the file that holds a project's space id.