Skip to content
TraceItX Docs
Documentation

Ticket API

Create a ticket from CI, a script, or a bot — without opening the dashboard.

Overview

The ticket API lets your own systems file a card onto a TraceItX board directly — a failing CI run, a cron job, a Slack bot, anything that isn't a human clicking around the dashboard. It's v1: fields may be added to requests and responses without notice, but nothing documented on this page will change meaning or be removed within v1.

Get a token

Tokens are managed from Settings → API tokens → Create in the dashboard — an organisation admin role is required for every token operation (create, list, rename/re-scope, revoke); a non-admin following this path will get a permission error. Each token has:

  • A name. Up to 80 characters. This is what appears as the ticket's author in TraceItX — on the card and in activity history — so name it after the system that's using it (ci-bot, support-triage), not a person. It does not appear in @mentions: a token is deliberately left out of the mention list, since there's no one behind it to notify.
  • All projects, or selected projects. A token can reach every project in the organisation, or a specific list you choose when creating it. Narrowing to only the projects a given integration actually needs limits the blast radius if that token ever leaks — a CI job that only files tickets against one project has no business holding a token that can reach every other one too.
The token is shown once. Copy it now — TraceItX stores only a hash and cannot show it to you again. If you lose it, revoke it and create a new one.

An API token is not an SDK key. An SDK key ships inside your application — a web bundle or a decompiled binary yields it — which is why the ingest endpoint it authenticates only ever accepts reports and can't be used to read or change anything. An API token can create tickets in your projects (v1 has no update endpoint — a token can't modify a ticket after creating it). Never embed an API token inside an application you ship; it belongs in CI secrets or a server environment, not in a client.

Authenticate

Send the token as a bearer token on every request:

Authorization: Bearer txx_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Any problem with the credential — missing, malformed, unknown, or revoked — returns 401 with { "error": "invalid_api_token" }, deliberately without saying which: telling a caller a token is "revoked" rather than simply "invalid" would confirm the token once existed. Revoking a token takes effect immediately.

Create a ticket

POST /api/v1/tickets
curl -X POST https://traceitx.com/api/v1/tickets \
  -H "Authorization: Bearer $TRACEITX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Checkout crashes on iOS 18"}'

Fields

FieldTypeNotes
titlestring, required1–200 characters.
descriptionstringOptional. Up to 20,000 characters.
projectIduuidDefaults to the token's only reachable project; required once the token reaches more than one.
boardIduuidDefaults to the project's first board.
columnIduuidDefaults to the board's leftmost column.
prioritystringOne of none, low, medium, high. Defaults to none.
assigneeUserIduuid, nullableMust be a member of the organisation.
agentRepositoryIduuid, nullableMust be a repository already bound to the project.
startsAtstring, nullableYYYY-MM-DD.
dueAtstring, nullableYYYY-MM-DD.

projectId, boardId, and columnId resolve in order: if you don't name a project, the token must reach exactly one — the request fails once it reaches more than one, rather than guessing. If you don't name a board, TraceItX uses the resolved project's first board. If you don't name a column, TraceItX uses that board's leftmost column.

Assigning to the organisation's agent starts a run. If assigneeUserId names the org's AI agent, TraceItX enqueues an autonomous run against the ticket — the same behaviour as assigning a card to the agent from the dashboard — which consumes credits and may open a pull request. This is intentional: it's what makes agentRepositoryId useful, since that field selects which bound repository the run works against. If you only want a ticket to appear on the board, don't set assigneeUserId to the agent.

On success, the API returns 201 with:

{
  "id": "<uuid>",
  "title": "Checkout crashes on iOS 18",
  "projectId": "<uuid>",
  "boardId": "<uuid>",
  "columnId": "<uuid>",
  "createdAt": "<ISO 8601>",
  "url": "<dashboard deep link>"
}

url is a deep link straight to the new card in the dashboard — print it in CI output so a person can click through to it.

Idempotency

A CI job that retries after a timeout must not file the same ticket twice. Send an Idempotency-Key and a repeat with the same key returns the original ticket unchanged and creates nothing new:

-H "Idempotency-Key: ci-run-${GITHUB_RUN_ID}"

Keys are scoped to the token — the same key used by two different tokens is two different keys. Use a key that is unique per ticket you intend to create — deriving it from something already unique to the run, like the ci-run-${GITHUB_RUN_ID} example above, is the natural approach. Don't reuse a key expecting it to have expired: reusing one replays the original ticket rather than creating a new one.

Errors

StatusErrorMeaning
400invalid_inputBody failed validation, including an unrecognised field.
400project_requiredThe token reaches more than one project; name one.
400invalid_date_rangestartsAt is after dueAt.
400not_a_memberassigneeUserId is not a member of the organisation.
400invalid_agent_repositoryagentRepositoryId is not a repository bound to the project.
400invalid_idempotency_keyEmpty, or longer than 255 characters.
401invalid_api_tokenMissing, malformed, unknown, or revoked token.
403insufficient_scopeThe token lacks tickets:write.
404project_not_foundNo such project, or the token cannot reach it.
404board_not_foundNo such board, or it belongs to another project.
404column_not_foundNo such column, or it belongs to another board.
429Over 60 requests/minute for this token.

project_not_found deliberately covers both "does not exist" and "not yours" — the same response either way, on purpose, so a token can't be used to map an organisation it has no access to by comparing error codes.

Limits

LimitValue
Rate limit (per token)60 requests / minute
AttachmentsNot supported in v1

Versioning

Within /api/v1: fields may be added to requests and responses without notice; existing fields will not be removed or change meaning. Don't validate responses against a strict shape that rejects unknown fields — a client that does will break on a purely additive change.