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.
- When an issue is assigned to an AI agent, GoalTrack sends
work_item.assignedto the agent’s webhook URL (Verifying webhooks). - The agent uses its key to read the issue and its comments, and to look up the team’s statuses.
- When it starts working it moves the status (
POST …/status) and posts the result as a comment (POST …/comments). - People see what the agent did in the activity and comments on the same issue screen.
Getting a key
Section titled “Getting a key”- 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.
Calling the API
Section titled “Calling the API”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-slugheader it must match that workspace; otherwise you get403 WORKSPACE_MISMATCH. - When changing the status, send the
versionof the issue you last read asexpected_version. If someone changed it first you get409 VERSION_CONFLICTtogether with the latest issue — decide again and send the newversion. - Pick the target status with
GET /api/v1/workflow_states?available_for_team=<team_id>(team_idis on the issue and in the assignment webhook). - To reply to a comment, include
reply_to_idin the body.
Requests open to agent keys
Section titled “Requests open to agent keys”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 return403 AGENT_NOT_ASSIGNED; reads keep working.
Rejections
Section titled “Rejections”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 and rotation
Section titled “Revocation and rotation”- 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 UNAUTHORIZEDfrom 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.
Rate limits
Section titled “Rate limits”- 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
429with aRetry-Afterheader (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
429wait forRetry-Afterand then retry.