Skip to content

AI agent keys

An AI agent key is the agent’s own identity. Work done with a person’s API key (gtk_) is recorded under that person’s name; work done with an agent key (gtag_) is recorded under the agent’s name, and the issue screen marks it with a ✦ AI badge.

  1. When an issue is assigned to an AI agent, GoalTrack sends work_item.assigned to the agent’s webhook URL (Verifying webhooks).
  2. The agent uses its key to read the issue and its comments, and to look up the team’s statuses.
  3. When it starts working it moves the status (POST …/status) and posts the result as a comment (POST …/comments).
  4. People see what the agent did in the activity and comments on the same issue screen.
  • For now, a GoalTrack operator registers the agent and creates its key. The full key (starting with gtag_) is handed over once at creation and GoalTrack keeps only a hash — put it in your secret store right away. There is no screen yet for workspace admins to create agents themselves.
  • Agent keys do not expire. If a key leaks, ask the operator to rotate or revoke it.
터미널 창
curl "https://goaltrack.dyld.kr/api/v1/work_items/$ISSUE_ID" \
-H "Authorization: Bearer $GOALTRACK_AGENT_KEY"
터미널 창
curl -X POST "https://goaltrack.dyld.kr/api/v1/work_items/$ISSUE_ID/status" \
-H "Authorization: Bearer $GOALTRACK_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{ "status_id": "<target status id>", "expected_version": 3 }'
  • The key is bound to the agent’s workspace. If you send an x-workspace-slug header it must match that workspace; otherwise you get 403 WORKSPACE_MISMATCH.
  • When changing the status, send the version of the issue you last read as expected_version. If someone changed it first you get 409 VERSION_CONFLICT together with the latest issue — decide again and send the new version.
  • Pick the target status with GET /api/v1/workflow_states?available_for_team=<team_id> (team_id is on the issue and in the assignment webhook).
  • To reply to a comment, include reply_to_id in the body.

Only the requests below accept an agent key. Calling any other request with an agent key returns 401 UNAUTHORIZED (including requests open to personal API keys).

Request Scope Per-minute limit
GET /api/v1/work_items read 120
GET /api/v1/work_items/:id read 120
GET /api/v1/work_items/by-short/:shortId read 120
GET /api/v1/work_items/:id/comments read 120
GET /api/v1/workflow_states read 120
POST /api/v1/work_items/:id/status assigned_write 120
POST /api/v1/work_items/:id/comments assigned_write 120
  • read — reads issues, comments, and statuses in the agent’s workspace. Other people’s draft issues are not visible (404).
  • assigned_write — writes only to issues assigned to the agent. Once the assignee changes to someone else, writes to that issue immediately return 403 AGENT_NOT_ASSIGNED; reads keep working.

Checks run in the order below. If an earlier check rejects the request, later ones are not evaluated.

Situation Response
Wrong key, or the old key after a rotation 401 UNAUTHORIZED
Revoked key 401 AGENT_KEY_REVOKED
The agent is not a member of the workspace 403 FORBIDDEN
The agent account is suspended 403 ACCOUNT_SUSPENDED
x-workspace-slug differs from the agent’s workspace 403 WORKSPACE_MISMATCH
The workspace is suspended 403 WORKSPACE_SUSPENDED_FULL or 403 WORKSPACE_SUSPENDED_READ_ONLY (a read-only suspension blocks writes only)
A write while the agent has the viewer role 403 WRITER_ROLE_REQUIRED
The issue to write to does not exist, is in another workspace, or is someone else’s draft 404 NOT_FOUND
The issue to write to is not assigned to the agent 403 AGENT_NOT_ASSIGNED

All codes and what to do about them are listed in Error codes.

  • Revocation: once the operator revokes the agent, the next request gets 401 AGENT_KEY_REVOKED.
  • Rotation: when the operator creates a new key, it is handed over once and the old key returns 401 UNAUTHORIZED from that moment. There is no grace period where both keys work, so switch to the new key right away.
  • Requests already in progress run to completion. Invalidation applies from the next request.
  • Limits count all requests from one agent together — any mix of the requests in the table adds up to 120 per minute, reset every minute. Exceed one and you get 429 with a Retry-After header (seconds). Wait that long, then send again.
  • There are other caps against abuse as well (for example, repeatedly sending an invalid key). Whichever limit you hit, on 429 wait for Retry-After and then retry.