@atollhq/skill-gemini 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/install.mjs +111 -0
- package/package.json +26 -0
- package/skill/SKILL.md +142 -0
- package/skill/references/api-endpoints.md +387 -0
- package/skill/references/api-fields.md +249 -0
package/bin/install.mjs
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from 'node:fs'
|
|
4
|
+
import { join, dirname } from 'node:path'
|
|
5
|
+
import { homedir } from 'node:os'
|
|
6
|
+
import { fileURLToPath } from 'node:url'
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
9
|
+
|
|
10
|
+
function parseArgs(argv) {
|
|
11
|
+
const args = {}
|
|
12
|
+
for (let i = 2; i < argv.length; i++) {
|
|
13
|
+
if (argv[i] === '--key' && argv[i + 1]) args.key = argv[++i]
|
|
14
|
+
else if (argv[i] === '--org' && argv[i + 1]) args.org = argv[++i]
|
|
15
|
+
else if (argv[i] === '--help' || argv[i] === '-h') args.help = true
|
|
16
|
+
}
|
|
17
|
+
return args
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function printUsage() {
|
|
21
|
+
console.log(`
|
|
22
|
+
Usage: npx @atollhq/skill-gemini --key <api-key> --org <org-slug>
|
|
23
|
+
|
|
24
|
+
Options:
|
|
25
|
+
--key Atoll API key (sk_atoll_...)
|
|
26
|
+
--org Organization slug
|
|
27
|
+
--help Show this help message
|
|
28
|
+
|
|
29
|
+
Installs the Atoll integration for Gemini CLI:
|
|
30
|
+
- Writes GEMINI.md with API reference to ~/.gemini/
|
|
31
|
+
- Sets ATOLL_API_KEY and ATOLL_ORG_SLUG env vars
|
|
32
|
+
`)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const args = parseArgs(process.argv)
|
|
36
|
+
|
|
37
|
+
if (args.help) { printUsage(); process.exit(0) }
|
|
38
|
+
|
|
39
|
+
if (!args.key || !args.org) {
|
|
40
|
+
console.error('Error: --key and --org are required\n')
|
|
41
|
+
printUsage()
|
|
42
|
+
process.exit(1)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!args.key.startsWith('sk_atoll_')) {
|
|
46
|
+
console.error('Error: API key must start with sk_atoll_')
|
|
47
|
+
process.exit(1)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 1. Write GEMINI.md to ~/.gemini/
|
|
51
|
+
const geminiDir = join(homedir(), '.gemini')
|
|
52
|
+
mkdirSync(geminiDir, { recursive: true })
|
|
53
|
+
|
|
54
|
+
const skillDir = join(__dirname, '..', 'skill')
|
|
55
|
+
const skillMd = readFileSync(join(skillDir, 'SKILL.md'), 'utf-8')
|
|
56
|
+
const body = skillMd.replace(/^---[\s\S]*?---\n*/, '')
|
|
57
|
+
|
|
58
|
+
const geminiMd = `# Atoll Integration
|
|
59
|
+
|
|
60
|
+
${body}
|
|
61
|
+
|
|
62
|
+
## Credentials
|
|
63
|
+
|
|
64
|
+
- API Key: set as ATOLL_API_KEY environment variable
|
|
65
|
+
- Org: ${args.org}
|
|
66
|
+
`
|
|
67
|
+
|
|
68
|
+
const geminiPath = join(geminiDir, 'GEMINI.md')
|
|
69
|
+
if (existsSync(geminiPath)) {
|
|
70
|
+
const existing = readFileSync(geminiPath, 'utf-8')
|
|
71
|
+
if (existing.includes('# Atoll Integration')) {
|
|
72
|
+
const replaced = existing.replace(/# Atoll Integration[\s\S]*$/, geminiMd.trim())
|
|
73
|
+
writeFileSync(geminiPath, replaced + '\n')
|
|
74
|
+
} else {
|
|
75
|
+
writeFileSync(geminiPath, existing.trimEnd() + '\n\n' + geminiMd)
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
writeFileSync(geminiPath, geminiMd)
|
|
79
|
+
}
|
|
80
|
+
console.log(`Wrote Atoll instructions to ${geminiPath}`)
|
|
81
|
+
|
|
82
|
+
// 2. Copy reference files
|
|
83
|
+
const refsDir = join(geminiDir, 'atoll-references')
|
|
84
|
+
mkdirSync(refsDir, { recursive: true })
|
|
85
|
+
for (const file of ['api-endpoints.md', 'api-fields.md']) {
|
|
86
|
+
copyFileSync(join(skillDir, 'references', file), join(refsDir, file))
|
|
87
|
+
}
|
|
88
|
+
console.log(`Copied API references to ${refsDir}`)
|
|
89
|
+
|
|
90
|
+
// 3. Set env vars in shell profile
|
|
91
|
+
const shell = process.env.SHELL || '/bin/bash'
|
|
92
|
+
const profilePath = shell.includes('zsh')
|
|
93
|
+
? join(homedir(), '.zshrc')
|
|
94
|
+
: join(homedir(), '.bashrc')
|
|
95
|
+
|
|
96
|
+
const envBlock = `\n# Atoll (added by @atollhq/skill-gemini)\nexport ATOLL_API_KEY="${args.key}"\nexport ATOLL_ORG_SLUG="${args.org}"\n`
|
|
97
|
+
|
|
98
|
+
if (existsSync(profilePath)) {
|
|
99
|
+
const profile = readFileSync(profilePath, 'utf-8')
|
|
100
|
+
if (profile.includes('ATOLL_API_KEY')) {
|
|
101
|
+
console.log(`ATOLL_API_KEY already set in ${profilePath} — update manually if needed`)
|
|
102
|
+
} else {
|
|
103
|
+
writeFileSync(profilePath, profile.trimEnd() + '\n' + envBlock)
|
|
104
|
+
console.log(`Added ATOLL_API_KEY and ATOLL_ORG_SLUG to ${profilePath}`)
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
writeFileSync(profilePath, envBlock)
|
|
108
|
+
console.log(`Created ${profilePath} with ATOLL_API_KEY and ATOLL_ORG_SLUG`)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log(`\nDone! Restart your shell, then Gemini CLI will have access to the Atoll API.`)
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atollhq/skill-gemini",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Install the Atoll project management integration for Gemini CLI",
|
|
5
|
+
"bin": {
|
|
6
|
+
"skill-gemini": "./bin/install.mjs"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"skill/"
|
|
11
|
+
],
|
|
12
|
+
"keywords": [
|
|
13
|
+
"atoll",
|
|
14
|
+
"gemini",
|
|
15
|
+
"google",
|
|
16
|
+
"project-management",
|
|
17
|
+
"ai-agent"
|
|
18
|
+
],
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/atollhq/atoll.git",
|
|
22
|
+
"directory": "packages/skill-gemini"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"type": "module"
|
|
26
|
+
}
|
package/skill/SKILL.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atoll-api
|
|
3
|
+
description: Interact with the Atoll project management API for managing tasks, projects, goals, KPIs, initiatives, milestones, comments, members, teams, labels, dependencies, automation, and webhooks. Use when making HTTP requests to atollhq.com, working with Atoll issues/tasks, creating or updating projects, managing team workflows, tracking goals and KPIs, or building agent integrations with the Atoll platform. Atoll treats agents as equal team members — not assistants — with their own goals, assigned work, and the ability to self-direct based on business context.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Atoll API
|
|
7
|
+
|
|
8
|
+
Base URL: `https://atollhq.com`
|
|
9
|
+
|
|
10
|
+
## How Atoll Works
|
|
11
|
+
|
|
12
|
+
Atoll connects strategy to execution through a reasoning chain:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
Goals (directional objectives with deadlines)
|
|
16
|
+
→ KPIs (live metrics — manual, webhook, or API-fed)
|
|
17
|
+
→ Initiatives (bets expected to move specific KPIs)
|
|
18
|
+
→ Milestones + Issues (execution work)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This means an agent can reason: "We're off pace on paying_customers → the Content Pipeline initiative should drive signups but has stalled issues → unblocking those is the highest-leverage action right now."
|
|
22
|
+
|
|
23
|
+
Agents are org members with the same API, same permissions, same ability to create goals, update KPIs, propose initiatives, and execute work. The system does not distinguish between human and agent actions.
|
|
24
|
+
|
|
25
|
+
## Authentication
|
|
26
|
+
|
|
27
|
+
All requests require: `Authorization: Bearer sk_atoll_<key>`
|
|
28
|
+
|
|
29
|
+
Verify with: `GET /api/auth/me`
|
|
30
|
+
|
|
31
|
+
API keys are generated in **Settings > Members > Add Agent**. Store as `$ATOLL_API_KEY`.
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
export ATOLL_API_KEY="sk_atoll_..."
|
|
37
|
+
|
|
38
|
+
# Helper function
|
|
39
|
+
atoll() {
|
|
40
|
+
curl -s -H "Authorization: Bearer $ATOLL_API_KEY" \
|
|
41
|
+
-H "Content-Type: application/json" \
|
|
42
|
+
"https://atollhq.com$1" "${@:2}" | python3 -m json.tool
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# List orgs
|
|
46
|
+
atoll /api/orgs
|
|
47
|
+
|
|
48
|
+
# List tasks
|
|
49
|
+
atoll "/api/orgs/{orgId}/issues?projectId={projectId}"
|
|
50
|
+
|
|
51
|
+
# Create a task
|
|
52
|
+
atoll /api/orgs/{orgId}/issues -X POST -d '{"title":"Fix login bug","status":"todo","priority":1}'
|
|
53
|
+
|
|
54
|
+
# Update a task
|
|
55
|
+
atoll /api/orgs/{orgId}/issues/{issueId} -X PATCH -d '{"status":"in_progress"}'
|
|
56
|
+
|
|
57
|
+
# Add a comment
|
|
58
|
+
atoll /api/orgs/{orgId}/issues/{issueId}/comments -X POST -d '{"body":"Working on this now"}'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## The Heartbeat Loop
|
|
62
|
+
|
|
63
|
+
The primary pattern for autonomous agents. `GET /api/orgs/{id}/heartbeat` returns a computed briefing:
|
|
64
|
+
|
|
65
|
+
- **Goal status** with days remaining
|
|
66
|
+
- **KPI pace**: `pace_needed` vs `pace_actual`, trend (`accelerating`/`decelerating`/`flat`), staleness
|
|
67
|
+
- **Initiative progress**: total/completed/stalled/blocked issue counts, expected KPI impacts
|
|
68
|
+
- **Assigned work** for this agent
|
|
69
|
+
- **Signals** sorted by severity — the agent's prioritized to-do list
|
|
70
|
+
|
|
71
|
+
Signal types: `kpi_off_pace`, `kpi_stale`, `issue_stale`, `issue_blocked`, `milestone_overdue`, `initiative_stalled`, `webhook_failing`. Severity: `info`, `warning`, `critical`.
|
|
72
|
+
|
|
73
|
+
**The agent loop:**
|
|
74
|
+
1. Call heartbeat
|
|
75
|
+
2. Read signals (highest severity first)
|
|
76
|
+
3. Reason about highest-leverage action given KPI pace and initiative state
|
|
77
|
+
4. Execute (unblock issues, update KPIs, create work, report progress)
|
|
78
|
+
5. Repeat
|
|
79
|
+
|
|
80
|
+
## Other Common Workflows
|
|
81
|
+
|
|
82
|
+
### Pick up and complete a task
|
|
83
|
+
|
|
84
|
+
1. `GET /api/orgs/{id}/issues?status=todo&assigneeId={agentId}` -- find assigned work
|
|
85
|
+
2. `PATCH /api/orgs/{id}/issues/{issueId}` with `{"status":"in_progress"}` -- start work
|
|
86
|
+
3. `POST /api/orgs/{id}/issues/{issueId}/comments` with `{"body":"Progress update..."}` -- report progress
|
|
87
|
+
4. `PATCH /api/orgs/{id}/issues/{issueId}` with `{"status":"done"}` -- complete
|
|
88
|
+
|
|
89
|
+
### Set up the strategy chain
|
|
90
|
+
|
|
91
|
+
1. `POST /api/orgs/{id}/goals` -- create goal with `target_date`
|
|
92
|
+
2. `POST /api/orgs/{id}/kpis` -- attach KPI with `goal_id`, `target_value`, `target_direction`
|
|
93
|
+
3. `POST /api/orgs/{id}/kpis/{kpiId}/snapshots` -- record measurement (auto-updates `current_value`)
|
|
94
|
+
4. `POST /api/orgs/{id}/initiatives` -- create initiative linked to goal
|
|
95
|
+
5. `POST /api/orgs/{id}/initiatives/{id}/kpi-impacts` -- declare expected KPI impact
|
|
96
|
+
6. Link issues and milestones to the initiative
|
|
97
|
+
|
|
98
|
+
Every KPI snapshot can be attributed to an initiative or issue, building a record of *what actually moved the numbers*.
|
|
99
|
+
|
|
100
|
+
### Bulk create tasks from a plan
|
|
101
|
+
|
|
102
|
+
`POST /api/orgs/{id}/issues/bulk` with `{ "issues": [{...}, ...] }` (max 50).
|
|
103
|
+
|
|
104
|
+
## API Reference
|
|
105
|
+
|
|
106
|
+
Full endpoint tables and field schemas:
|
|
107
|
+
- **[references/api-endpoints.md](references/api-endpoints.md)** -- all endpoints organized by resource
|
|
108
|
+
- **[references/api-fields.md](references/api-fields.md)** -- request/response schemas, field definitions, enums
|
|
109
|
+
|
|
110
|
+
### Key resources
|
|
111
|
+
|
|
112
|
+
| Resource | Create | Read | Update | Delete |
|
|
113
|
+
|----------|--------|------|--------|--------|
|
|
114
|
+
| Orgs | POST `/api/orgs` | GET `/api/orgs` | PATCH `/api/orgs/{id}` | DELETE `/api/orgs/{id}` |
|
|
115
|
+
| Projects | POST `.../projects` | GET `.../projects` | PATCH `.../projects/{id}` | DELETE `.../projects/{id}` |
|
|
116
|
+
| Tasks | POST `.../issues` | GET `.../issues` | PATCH `.../issues/{id}` | DELETE `.../issues/{id}` |
|
|
117
|
+
| Goals | POST `.../goals` | GET `.../goals` | PATCH `.../goals/{id}` | DELETE `.../goals/{id}` |
|
|
118
|
+
| KPIs | POST `.../kpis` | GET `.../kpis` | PATCH `.../kpis/{id}` | DELETE `.../kpis/{id}` |
|
|
119
|
+
| Initiatives | POST `.../initiatives` | GET `.../initiatives` | PATCH `.../initiatives/{id}` | DELETE `.../initiatives/{id}` |
|
|
120
|
+
| Milestones | POST `.../milestones` | GET `.../milestones` | PATCH `.../milestones/{id}` | DELETE `.../milestones/{id}` |
|
|
121
|
+
| Comments | POST `.../comments` | GET `.../comments` | PATCH `.../comments/{id}` | DELETE `.../comments/{id}` |
|
|
122
|
+
| Subtasks | POST `.../subtasks` | GET `.../subtasks` | PATCH `.../subtasks/{id}` | DELETE `.../subtasks/{id}` |
|
|
123
|
+
|
|
124
|
+
All endpoints are under `/api/orgs/{orgId}/...`.
|
|
125
|
+
|
|
126
|
+
### Quick enum reference
|
|
127
|
+
|
|
128
|
+
- **Task status**: `backlog`, `todo`, `in_progress`, `done`, `cancelled` (custom per project)
|
|
129
|
+
- **Priority**: `0` urgent, `1` high, `2` medium, `3` low
|
|
130
|
+
- **Goal status**: `active`, `achieved`, `missed`, `paused`, `cancelled`
|
|
131
|
+
- **Initiative status**: `proposed`, `active`, `completed`, `paused`, `cancelled`
|
|
132
|
+
- **KPI direction**: `increase`, `decrease`, `maintain`
|
|
133
|
+
- **Member role**: `owner`, `admin`, `member`, `guest`
|
|
134
|
+
|
|
135
|
+
## Notes
|
|
136
|
+
|
|
137
|
+
- Request bodies accept camelCase; responses use snake_case
|
|
138
|
+
- Descriptions and comments support Markdown
|
|
139
|
+
- All timestamps are ISO 8601 UTC
|
|
140
|
+
- Board statuses are customizable per project -- query `/board-columns` for available values
|
|
141
|
+
- API changes appear in real-time on the web board
|
|
142
|
+
- List endpoints support `limit` (default 25, max 100) and `offset` pagination
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
# Atoll API Endpoint Reference
|
|
2
|
+
|
|
3
|
+
Base URL: `https://atollhq.com`
|
|
4
|
+
|
|
5
|
+
All endpoints require `Authorization: Bearer sk_atoll_...` header.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Organizations](#organizations)
|
|
10
|
+
- [Projects](#projects)
|
|
11
|
+
- [Project Members](#project-members)
|
|
12
|
+
- [Project Teams](#project-teams)
|
|
13
|
+
- [Tasks (Issues)](#tasks-issues)
|
|
14
|
+
- [Dependencies](#dependencies)
|
|
15
|
+
- [Comments](#comments)
|
|
16
|
+
- [Subtasks](#subtasks)
|
|
17
|
+
- [Members](#members)
|
|
18
|
+
- [Milestones](#milestones)
|
|
19
|
+
- [Goals](#goals)
|
|
20
|
+
- [KPIs](#kpis)
|
|
21
|
+
- [Initiatives](#initiatives)
|
|
22
|
+
- [Initiative Links](#initiative-links)
|
|
23
|
+
- [Heartbeat](#heartbeat)
|
|
24
|
+
- [Activity](#activity)
|
|
25
|
+
- [Teams](#teams)
|
|
26
|
+
- [Labels](#labels)
|
|
27
|
+
- [Board Columns](#board-columns)
|
|
28
|
+
- [Board Views](#board-views)
|
|
29
|
+
- [Custom Views](#custom-views)
|
|
30
|
+
- [Issue Templates](#issue-templates)
|
|
31
|
+
- [Attachments](#attachments)
|
|
32
|
+
- [Profile Images](#profile-images)
|
|
33
|
+
- [PR Links](#pr-links)
|
|
34
|
+
- [Project Status Updates](#project-status-updates)
|
|
35
|
+
- [Project Health](#project-health)
|
|
36
|
+
- [Analytics](#analytics)
|
|
37
|
+
- [Automation Rules](#automation-rules)
|
|
38
|
+
- [Webhooks](#webhooks)
|
|
39
|
+
- [Notifications](#notifications)
|
|
40
|
+
- [Agents](#agents)
|
|
41
|
+
- [GitHub Integration](#github-integration)
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Organizations
|
|
46
|
+
|
|
47
|
+
| Method | Endpoint | Description |
|
|
48
|
+
|--------|----------|-------------|
|
|
49
|
+
| GET | `/api/orgs` | List your orgs |
|
|
50
|
+
| POST | `/api/orgs` | Create an org (`{ name }`) |
|
|
51
|
+
| GET | `/api/orgs/{id}` | Get org details |
|
|
52
|
+
| PATCH | `/api/orgs/{id}` | Update org |
|
|
53
|
+
| DELETE | `/api/orgs/{id}` | Delete org |
|
|
54
|
+
|
|
55
|
+
## Projects
|
|
56
|
+
|
|
57
|
+
| Method | Endpoint | Description |
|
|
58
|
+
|--------|----------|-------------|
|
|
59
|
+
| GET | `/api/orgs/{id}/projects` | List projects (visibility-filtered) |
|
|
60
|
+
| POST | `/api/orgs/{id}/projects` | Create project (`{ name, description?, visibility?, color?, icon?, github_repo? }`) |
|
|
61
|
+
| GET | `/api/orgs/{id}/projects/{projectId}` | Get project with issues |
|
|
62
|
+
| PATCH | `/api/orgs/{id}/projects/{projectId}` | Update project (`{ name?, description?, status?, visibility?, color?, icon? }`) |
|
|
63
|
+
| DELETE | `/api/orgs/{id}/projects/{projectId}` | Delete project (owner/admin) |
|
|
64
|
+
|
|
65
|
+
Guest users only see projects they are assigned to.
|
|
66
|
+
|
|
67
|
+
## Project Members
|
|
68
|
+
|
|
69
|
+
| Method | Endpoint | Description |
|
|
70
|
+
|--------|----------|-------------|
|
|
71
|
+
| GET | `/api/orgs/{id}/projects/{projectId}/members` | List project members |
|
|
72
|
+
| POST | `/api/orgs/{id}/projects/{projectId}/members` | Add member (`{ memberId, accessLevel? }`) |
|
|
73
|
+
| PATCH | `/api/orgs/{id}/projects/{projectId}/members` | Update access (`{ memberId, accessLevel }`) |
|
|
74
|
+
| DELETE | `/api/orgs/{id}/projects/{projectId}/members?memberId=...` | Remove member |
|
|
75
|
+
|
|
76
|
+
Access levels: `view`, `edit`, `admin` (default: `view`).
|
|
77
|
+
|
|
78
|
+
## Project Teams
|
|
79
|
+
|
|
80
|
+
| Method | Endpoint | Description |
|
|
81
|
+
|--------|----------|-------------|
|
|
82
|
+
| GET | `/api/orgs/{id}/projects/{projectId}/teams` | List project teams |
|
|
83
|
+
| POST | `/api/orgs/{id}/projects/{projectId}/teams` | Add team (`{ teamId }`) |
|
|
84
|
+
| DELETE | `/api/orgs/{id}/projects/{projectId}/teams?teamId=...` | Remove team |
|
|
85
|
+
|
|
86
|
+
## Tasks (Issues)
|
|
87
|
+
|
|
88
|
+
| Method | Endpoint | Description |
|
|
89
|
+
|--------|----------|-------------|
|
|
90
|
+
| GET | `/api/orgs/{id}/issues` | List tasks (see filters below) |
|
|
91
|
+
| POST | `/api/orgs/{id}/issues` | Create task |
|
|
92
|
+
| GET | `/api/orgs/{id}/issues/{issueId}` | Get task detail |
|
|
93
|
+
| PATCH | `/api/orgs/{id}/issues/{issueId}` | Update task |
|
|
94
|
+
| DELETE | `/api/orgs/{id}/issues/{issueId}` | Delete task (admin/owner only) |
|
|
95
|
+
| POST | `/api/orgs/{id}/issues/bulk` | Bulk create tasks (up to 50) |
|
|
96
|
+
| GET | `/api/orgs/{id}/issues/search?q=...` | Search tasks by title |
|
|
97
|
+
|
|
98
|
+
**List filters** (query params):
|
|
99
|
+
- `status` -- `backlog`, `todo`, `in_progress`, `done`, `cancelled`
|
|
100
|
+
- `priority` -- `0` (urgent), `1` (high), `2` (medium), `3` (low)
|
|
101
|
+
- `projectId`, `assigneeId`, `teamId`, `milestoneId`
|
|
102
|
+
- `q` -- search title and description (case-insensitive)
|
|
103
|
+
- `includeArchived` -- `true` to include archived tasks
|
|
104
|
+
- `orderBy` -- `created_at` (default), `updated_at`, `priority`, `due_date`, `title`, `status`
|
|
105
|
+
- `orderDir` -- `asc` or `desc` (default)
|
|
106
|
+
- `limit` -- max results (default 25, max 100)
|
|
107
|
+
- `offset` -- pagination offset
|
|
108
|
+
|
|
109
|
+
**GET task detail** returns enriched data: `milestone`, `assignee`, `assignees`, `sub_tasks`, `issue_labels`, and `isBlocked`.
|
|
110
|
+
|
|
111
|
+
## Dependencies
|
|
112
|
+
|
|
113
|
+
| Method | Endpoint | Description |
|
|
114
|
+
|--------|----------|-------------|
|
|
115
|
+
| GET | `/api/orgs/{id}/issues/{issueId}/dependencies` | List dependencies (`{ blocking, blockedBy }`) |
|
|
116
|
+
| POST | `/api/orgs/{id}/issues/{issueId}/dependencies` | Add dependency |
|
|
117
|
+
| DELETE | `/api/orgs/{id}/issues/{issueId}/dependencies/{depId}` | Remove dependency |
|
|
118
|
+
|
|
119
|
+
Add with `{ "blockedByIssueId": "uuid" }` or `{ "blockingIssueId": "uuid" }`. Circular dependencies rejected (400). Duplicates return 409.
|
|
120
|
+
|
|
121
|
+
## Comments
|
|
122
|
+
|
|
123
|
+
| Method | Endpoint | Description |
|
|
124
|
+
|--------|----------|-------------|
|
|
125
|
+
| GET | `/api/orgs/{id}/issues/{issueId}/comments` | List comments |
|
|
126
|
+
| POST | `/api/orgs/{id}/issues/{issueId}/comments` | Add comment (`{ body }`) |
|
|
127
|
+
| PATCH | `/api/orgs/{id}/issues/{issueId}/comments/{commentId}` | Edit comment |
|
|
128
|
+
| DELETE | `/api/orgs/{id}/issues/{issueId}/comments/{commentId}` | Delete comment |
|
|
129
|
+
|
|
130
|
+
## Subtasks
|
|
131
|
+
|
|
132
|
+
| Method | Endpoint | Description |
|
|
133
|
+
|--------|----------|-------------|
|
|
134
|
+
| GET | `/api/orgs/{id}/issues/{issueId}/subtasks` | List subtasks |
|
|
135
|
+
| POST | `/api/orgs/{id}/issues/{issueId}/subtasks` | Create subtask (`{ title }`) |
|
|
136
|
+
| PATCH | `/api/orgs/{id}/issues/{issueId}/subtasks/{subtaskId}` | Update subtask |
|
|
137
|
+
| DELETE | `/api/orgs/{id}/issues/{issueId}/subtasks/{subtaskId}` | Delete subtask |
|
|
138
|
+
|
|
139
|
+
## Members
|
|
140
|
+
|
|
141
|
+
| Method | Endpoint | Description |
|
|
142
|
+
|--------|----------|-------------|
|
|
143
|
+
| GET | `/api/orgs/{id}/members` | List members. Filter: `?type=human` or `?type=agent` |
|
|
144
|
+
| POST | `/api/orgs/{id}/members` | Invite human member (`{ email, role? }`) |
|
|
145
|
+
| PATCH | `/api/orgs/{id}/members/{memberId}` | Update member (`{ display_name?, role? }`) |
|
|
146
|
+
| DELETE | `/api/orgs/{id}/members/{memberId}` | Remove member |
|
|
147
|
+
| GET | `/api/orgs/{id}/profile` | Get your own member record |
|
|
148
|
+
|
|
149
|
+
Roles: `owner`, `admin`, `member`, `guest`.
|
|
150
|
+
|
|
151
|
+
## Milestones
|
|
152
|
+
|
|
153
|
+
| Method | Endpoint | Description |
|
|
154
|
+
|--------|----------|-------------|
|
|
155
|
+
| GET | `/api/orgs/{id}/projects/{projectId}/milestones` | List milestones |
|
|
156
|
+
| POST | `/api/orgs/{id}/projects/{projectId}/milestones` | Create milestone |
|
|
157
|
+
| GET | `/api/orgs/{id}/milestones/{milestoneId}` | Get milestone |
|
|
158
|
+
| PATCH | `/api/orgs/{id}/milestones/{milestoneId}` | Update milestone |
|
|
159
|
+
| DELETE | `/api/orgs/{id}/milestones/{milestoneId}` | Delete milestone |
|
|
160
|
+
|
|
161
|
+
## Goals
|
|
162
|
+
|
|
163
|
+
| Method | Endpoint | Description |
|
|
164
|
+
|--------|----------|-------------|
|
|
165
|
+
| GET | `/api/orgs/{id}/goals` | List goals (optional `?status=active`) |
|
|
166
|
+
| POST | `/api/orgs/{id}/goals` | Create goal |
|
|
167
|
+
| GET | `/api/orgs/{id}/goals/{goalId}` | Get goal |
|
|
168
|
+
| PATCH | `/api/orgs/{id}/goals/{goalId}` | Update goal |
|
|
169
|
+
| DELETE | `/api/orgs/{id}/goals/{goalId}` | Delete goal (admin/owner only) |
|
|
170
|
+
|
|
171
|
+
## KPIs
|
|
172
|
+
|
|
173
|
+
| Method | Endpoint | Description |
|
|
174
|
+
|--------|----------|-------------|
|
|
175
|
+
| GET | `/api/orgs/{id}/kpis` | List KPIs (optional `?goal_id=...`) |
|
|
176
|
+
| POST | `/api/orgs/{id}/kpis` | Create KPI |
|
|
177
|
+
| GET | `/api/orgs/{id}/kpis/{kpiId}` | Get KPI |
|
|
178
|
+
| PATCH | `/api/orgs/{id}/kpis/{kpiId}` | Update KPI |
|
|
179
|
+
| DELETE | `/api/orgs/{id}/kpis/{kpiId}` | Delete KPI (admin/owner only) |
|
|
180
|
+
| GET | `/api/orgs/{id}/kpis/{kpiId}/snapshots` | List snapshots (optional `?limit=50`) |
|
|
181
|
+
| POST | `/api/orgs/{id}/kpis/{kpiId}/snapshots` | Record a snapshot |
|
|
182
|
+
|
|
183
|
+
## Initiatives
|
|
184
|
+
|
|
185
|
+
| Method | Endpoint | Description |
|
|
186
|
+
|--------|----------|-------------|
|
|
187
|
+
| GET | `/api/orgs/{id}/initiatives` | List (optional `?goal_id=...&status=...&owner_id=...`) |
|
|
188
|
+
| POST | `/api/orgs/{id}/initiatives` | Create initiative |
|
|
189
|
+
| GET | `/api/orgs/{id}/initiatives/{initiativeId}` | Get initiative |
|
|
190
|
+
| PATCH | `/api/orgs/{id}/initiatives/{initiativeId}` | Update initiative |
|
|
191
|
+
| DELETE | `/api/orgs/{id}/initiatives/{initiativeId}` | Delete initiative (admin/owner only) |
|
|
192
|
+
| POST | `/api/orgs/{id}/initiatives/{initiativeId}/projects` | Add project to initiative |
|
|
193
|
+
| DELETE | `/api/orgs/{id}/initiatives/{initiativeId}/projects` | Remove project from initiative |
|
|
194
|
+
|
|
195
|
+
## Initiative Links
|
|
196
|
+
|
|
197
|
+
| Method | Endpoint | Description |
|
|
198
|
+
|--------|----------|-------------|
|
|
199
|
+
| GET | `.../initiatives/{id}/kpi-impacts` | List KPI impact links |
|
|
200
|
+
| POST | `.../initiatives/{id}/kpi-impacts` | Add (`{ kpi_id, expected_impact? }`) |
|
|
201
|
+
| DELETE | `.../initiatives/{id}/kpi-impacts/{impactId}` | Remove link |
|
|
202
|
+
| GET | `.../initiatives/{id}/issues` | List linked issues |
|
|
203
|
+
| POST | `.../initiatives/{id}/issues` | Link issue (`{ issue_id }`) |
|
|
204
|
+
| DELETE | `.../initiatives/{id}/issues/{issueId}` | Unlink issue |
|
|
205
|
+
| GET | `.../initiatives/{id}/milestones` | List linked milestones |
|
|
206
|
+
| POST | `.../initiatives/{id}/milestones` | Link milestone (`{ milestone_id }`) |
|
|
207
|
+
| DELETE | `.../initiatives/{id}/milestones/{milestoneId}` | Unlink milestone |
|
|
208
|
+
|
|
209
|
+
## Heartbeat
|
|
210
|
+
|
|
211
|
+
| Method | Endpoint | Description |
|
|
212
|
+
|--------|----------|-------------|
|
|
213
|
+
| GET | `/api/orgs/{id}/heartbeat` | Get heartbeat context for the authenticated agent |
|
|
214
|
+
|
|
215
|
+
Returns computed briefing with goal status, KPI pace/trend, initiative progress, assigned work, and signals.
|
|
216
|
+
|
|
217
|
+
Signal types: `kpi_off_pace`, `kpi_stale`, `issue_stale`, `issue_blocked`, `milestone_overdue`, `initiative_stalled`, `webhook_failing`. Severity: `info`, `warning`, `critical`.
|
|
218
|
+
|
|
219
|
+
## Activity
|
|
220
|
+
|
|
221
|
+
| Method | Endpoint | Description |
|
|
222
|
+
|--------|----------|-------------|
|
|
223
|
+
| GET | `/api/orgs/{id}/activity` | Org activity feed (`?limit=&offset=&filter=by_me\|mine`) |
|
|
224
|
+
| GET | `/api/orgs/{id}/issues/{issueId}/activity` | Task activity feed |
|
|
225
|
+
|
|
226
|
+
Filters: `by_me` = your actions; `mine` = activity on issues assigned to you.
|
|
227
|
+
|
|
228
|
+
## Teams
|
|
229
|
+
|
|
230
|
+
| Method | Endpoint | Description |
|
|
231
|
+
|--------|----------|-------------|
|
|
232
|
+
| GET | `/api/orgs/{id}/teams` | List teams |
|
|
233
|
+
| POST | `/api/orgs/{id}/teams` | Create team |
|
|
234
|
+
| GET | `/api/orgs/{id}/teams/{teamId}/members` | List team members |
|
|
235
|
+
| POST | `/api/orgs/{id}/teams/{teamId}/members` | Add member to team |
|
|
236
|
+
| DELETE | `/api/orgs/{id}/teams/{teamId}/members/{memberId}` | Remove from team |
|
|
237
|
+
|
|
238
|
+
## Labels
|
|
239
|
+
|
|
240
|
+
| Method | Endpoint | Description |
|
|
241
|
+
|--------|----------|-------------|
|
|
242
|
+
| GET | `/api/orgs/{id}/labels` | List all labels in this org |
|
|
243
|
+
| POST | `/api/orgs/{id}/labels` | Create label (`{ name, color?, description? }`) |
|
|
244
|
+
| POST | `/api/orgs/{id}/issues/{issueId}/labels` | Add label to task (`{ labelId }`) |
|
|
245
|
+
| DELETE | `/api/orgs/{id}/issues/{issueId}/labels/{labelId}` | Remove label from task |
|
|
246
|
+
|
|
247
|
+
## Board Columns
|
|
248
|
+
|
|
249
|
+
Custom statuses per project. Each column defines a valid status value.
|
|
250
|
+
|
|
251
|
+
| Method | Endpoint | Description |
|
|
252
|
+
|--------|----------|-------------|
|
|
253
|
+
| GET | `/api/orgs/{id}/projects/{projectId}/board-columns` | List columns (ordered by position) |
|
|
254
|
+
| POST | `/api/orgs/{id}/projects/{projectId}/board-columns` | Create column (`{ key, label, color?, position? }`) |
|
|
255
|
+
| PATCH | `/api/orgs/{id}/projects/{projectId}/board-columns/{columnId}` | Update column |
|
|
256
|
+
| DELETE | `/api/orgs/{id}/projects/{projectId}/board-columns/{columnId}` | Delete column (requires `reassignTo` in body) |
|
|
257
|
+
| PUT | `/api/orgs/{id}/projects/{projectId}/board-columns/reorder` | Bulk reorder (`{ columns: [{id, position}] }`) |
|
|
258
|
+
|
|
259
|
+
## Board Views
|
|
260
|
+
|
|
261
|
+
| Method | Endpoint | Description |
|
|
262
|
+
|--------|----------|-------------|
|
|
263
|
+
| GET | `/api/orgs/{id}/projects/{projectId}/board-views` | List views |
|
|
264
|
+
| POST | `/api/orgs/{id}/projects/{projectId}/board-views` | Create view (`{ name, columnIds: [...] }`) |
|
|
265
|
+
| PATCH | `/api/orgs/{id}/projects/{projectId}/board-views/{viewId}` | Update view |
|
|
266
|
+
| DELETE | `/api/orgs/{id}/projects/{projectId}/board-views/{viewId}` | Delete view (cannot delete default) |
|
|
267
|
+
|
|
268
|
+
## Custom Views
|
|
269
|
+
|
|
270
|
+
| Method | Endpoint | Description |
|
|
271
|
+
|--------|----------|-------------|
|
|
272
|
+
| GET | `/api/orgs/{id}/projects/{projectId}/custom-views` | List custom views |
|
|
273
|
+
| POST | `/api/orgs/{id}/projects/{projectId}/custom-views` | Create view |
|
|
274
|
+
| PATCH | `/api/orgs/{id}/projects/{projectId}/custom-views/{viewId}` | Update view |
|
|
275
|
+
| DELETE | `/api/orgs/{id}/projects/{projectId}/custom-views/{viewId}` | Delete view (cannot delete default) |
|
|
276
|
+
|
|
277
|
+
## Issue Templates
|
|
278
|
+
|
|
279
|
+
| Method | Endpoint | Description |
|
|
280
|
+
|--------|----------|-------------|
|
|
281
|
+
| GET | `/api/orgs/{id}/templates?projectId=...` | List templates |
|
|
282
|
+
| POST | `/api/orgs/{id}/templates` | Create template (`{ name, content, projectId? }`) |
|
|
283
|
+
| PATCH | `/api/orgs/{id}/templates/{templateId}` | Update template |
|
|
284
|
+
| DELETE | `/api/orgs/{id}/templates/{templateId}` | Delete template |
|
|
285
|
+
|
|
286
|
+
## Attachments
|
|
287
|
+
|
|
288
|
+
| Method | Endpoint | Description |
|
|
289
|
+
|--------|----------|-------------|
|
|
290
|
+
| GET | `/api/orgs/{id}/issues/{issueId}/attachments` | List attachments with URLs |
|
|
291
|
+
| POST | `/api/orgs/{id}/issues/{issueId}/attachments` | Upload file (multipart, `file` field, max 10MB) |
|
|
292
|
+
| DELETE | `/api/orgs/{id}/issues/{issueId}/attachments/{attachmentId}` | Delete attachment |
|
|
293
|
+
|
|
294
|
+
## Profile Images
|
|
295
|
+
|
|
296
|
+
| Method | Endpoint | Description |
|
|
297
|
+
|--------|----------|-------------|
|
|
298
|
+
| POST | `/api/orgs/{id}/members/{memberId}/avatar` | Upload avatar (multipart, max 2MB, JPEG/PNG/WebP/GIF) |
|
|
299
|
+
| DELETE | `/api/orgs/{id}/members/{memberId}/avatar` | Remove avatar |
|
|
300
|
+
|
|
301
|
+
## PR Links
|
|
302
|
+
|
|
303
|
+
| Method | Endpoint | Description |
|
|
304
|
+
|--------|----------|-------------|
|
|
305
|
+
| GET | `/api/orgs/{id}/issues/{issueId}/pr-links` | List linked pull requests |
|
|
306
|
+
|
|
307
|
+
PR links are created automatically via the GitHub webhook integration.
|
|
308
|
+
|
|
309
|
+
## Project Status Updates
|
|
310
|
+
|
|
311
|
+
| Method | Endpoint | Description |
|
|
312
|
+
|--------|----------|-------------|
|
|
313
|
+
| GET | `/api/orgs/{id}/projects/{projectId}/status-updates` | List status updates |
|
|
314
|
+
| POST | `/api/orgs/{id}/projects/{projectId}/status-updates` | Create status update (`{ status, summary }`) |
|
|
315
|
+
|
|
316
|
+
Status values: `on_track`, `at_risk`, `off_track`.
|
|
317
|
+
|
|
318
|
+
## Project Health
|
|
319
|
+
|
|
320
|
+
| Method | Endpoint | Description |
|
|
321
|
+
|--------|----------|-------------|
|
|
322
|
+
| GET | `/api/orgs/{id}/project-health` | Latest health status per project |
|
|
323
|
+
|
|
324
|
+
## Analytics
|
|
325
|
+
|
|
326
|
+
| Method | Endpoint | Description |
|
|
327
|
+
|--------|----------|-------------|
|
|
328
|
+
| GET | `/api/orgs/{id}/analytics?from=...&to=...` | Get analytics data |
|
|
329
|
+
|
|
330
|
+
Required: `from`, `to` (dates). Optional: `projectId`, `teamId`.
|
|
331
|
+
|
|
332
|
+
## Automation Rules
|
|
333
|
+
|
|
334
|
+
| Method | Endpoint | Description |
|
|
335
|
+
|--------|----------|-------------|
|
|
336
|
+
| GET | `/api/orgs/{id}/automation-rules` | List rules |
|
|
337
|
+
| POST | `/api/orgs/{id}/automation-rules` | Create rule (owner/admin) |
|
|
338
|
+
| GET | `/api/orgs/{id}/automation-rules/{ruleId}` | Get rule |
|
|
339
|
+
| PUT | `/api/orgs/{id}/automation-rules/{ruleId}` | Update rule (owner/admin) |
|
|
340
|
+
| DELETE | `/api/orgs/{id}/automation-rules/{ruleId}` | Delete rule (owner/admin) |
|
|
341
|
+
| GET | `/api/orgs/{id}/automation-rules/{ruleId}/activity` | Rule execution history |
|
|
342
|
+
| POST | `/api/orgs/{id}/automation-rules/{ruleId}/test` | Dry-run test |
|
|
343
|
+
|
|
344
|
+
Trigger events: `issue.created`, `issue.status_changed`, `issue.assigned`, `issue.priority_changed`.
|
|
345
|
+
|
|
346
|
+
## Webhooks
|
|
347
|
+
|
|
348
|
+
| Method | Endpoint | Description |
|
|
349
|
+
|--------|----------|-------------|
|
|
350
|
+
| GET | `/api/webhooks?orgId=...` | List webhooks |
|
|
351
|
+
| POST | `/api/webhooks?orgId=...` | Create webhook (owner/admin) |
|
|
352
|
+
| DELETE | `/api/webhooks/{id}` | Delete webhook (owner/admin) |
|
|
353
|
+
| GET | `/api/webhooks/{id}/deliveries` | List recent deliveries (last 50) |
|
|
354
|
+
| POST | `/api/webhooks/{id}/redeliver/{deliveryId}` | Redeliver a past payload |
|
|
355
|
+
| POST | `/api/webhooks/{id}/test` | Send ping test event |
|
|
356
|
+
|
|
357
|
+
URL must be HTTPS. Returns webhook record plus `secret` for HMAC verification.
|
|
358
|
+
|
|
359
|
+
## Notifications
|
|
360
|
+
|
|
361
|
+
| Method | Endpoint | Description |
|
|
362
|
+
|--------|----------|-------------|
|
|
363
|
+
| GET | `/api/notifications` | List notifications (last 50, unread first) |
|
|
364
|
+
| POST | `/api/notifications/{id}/read` | Mark as read |
|
|
365
|
+
| POST | `/api/notifications/read-all` | Mark all as read |
|
|
366
|
+
|
|
367
|
+
## Agents
|
|
368
|
+
|
|
369
|
+
| Method | Endpoint | Description |
|
|
370
|
+
|--------|----------|-------------|
|
|
371
|
+
| GET | `/api/orgs/{id}/agents` | List agents (owner/admin) |
|
|
372
|
+
| POST | `/api/orgs/{id}/agents` | Create agent (`{ name, role? }`) |
|
|
373
|
+
| DELETE | `/api/orgs/{id}/agents/{agentId}` | Revoke agent |
|
|
374
|
+
| GET | `/api/orgs/{id}/agents/{agentId}/keys` | List API keys |
|
|
375
|
+
| POST | `/api/orgs/{id}/agents/{agentId}/keys` | Generate new key |
|
|
376
|
+
| DELETE | `/api/orgs/{id}/agents/{agentId}/keys/{keyId}` | Revoke key |
|
|
377
|
+
| POST | `/api/orgs/{id}/agents/{agentId}/rotate` | Rotate all keys |
|
|
378
|
+
| POST | `/api/orgs/{id}/agents/{agentId}/install-snippets` | Get install snippets (`{ key }`) |
|
|
379
|
+
|
|
380
|
+
## GitHub Integration
|
|
381
|
+
|
|
382
|
+
| Method | Endpoint | Description |
|
|
383
|
+
|--------|----------|-------------|
|
|
384
|
+
| GET | `/api/orgs/{id}/github-connections` | List GitHub connections (owner/admin) |
|
|
385
|
+
| GET | `/api/integrations/github/repos` | List available repos |
|
|
386
|
+
| POST | `/api/integrations/github/connect` | Connect a repo |
|
|
387
|
+
| POST | `/api/integrations/github/disconnect` | Disconnect a repo |
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Atoll API Field Reference
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Task Fields](#task-fields)
|
|
6
|
+
- [Goal Fields](#goal-fields)
|
|
7
|
+
- [KPI Fields](#kpi-fields)
|
|
8
|
+
- [KPI Snapshots](#kpi-snapshots)
|
|
9
|
+
- [Initiative Fields](#initiative-fields)
|
|
10
|
+
- [Automation Rule Fields](#automation-rule-fields)
|
|
11
|
+
- [Custom View Fields](#custom-view-fields)
|
|
12
|
+
- [Webhook Fields](#webhook-fields)
|
|
13
|
+
- [Heartbeat Response](#heartbeat-response)
|
|
14
|
+
- [Analytics Response](#analytics-response)
|
|
15
|
+
- [Enums](#enums)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Task Fields
|
|
20
|
+
|
|
21
|
+
Request bodies accept **camelCase** (`assigneeId`, `projectId`). Snake_case also accepted for backward compatibility. Responses always use snake_case.
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"title": "Fix login bug",
|
|
26
|
+
"description": "Markdown supported",
|
|
27
|
+
"status": "todo",
|
|
28
|
+
"priority": 1,
|
|
29
|
+
"assigneeId": "member-uuid",
|
|
30
|
+
"assigneeIds": ["member-uuid-1", "member-uuid-2"],
|
|
31
|
+
"projectId": "project-uuid",
|
|
32
|
+
"milestoneId": "milestone-uuid",
|
|
33
|
+
"teamId": "team-uuid",
|
|
34
|
+
"startDate": "2026-03-01",
|
|
35
|
+
"dueDate": "2026-04-01",
|
|
36
|
+
"recurrenceType": "weekly",
|
|
37
|
+
"recurrenceInterval": 1,
|
|
38
|
+
"labelIds": ["label-uuid-1", "label-uuid-2"]
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
All fields work on both POST (create) and PATCH (update).
|
|
43
|
+
|
|
44
|
+
- **Multiple assignees**: Use `assigneeIds` (array). Legacy `assigneeId` (single) still works. Responses include `assignees` array with `id`, `display_name`, `type`, `avatar_url`.
|
|
45
|
+
- **Start date**: Sets when work begins. Combined with `dueDate`, defines the Gantt time span.
|
|
46
|
+
- **Recurring tasks**: Set `recurrenceType` + optional `recurrenceInterval` (default 1). When marked `done`, a new instance is auto-created. Response includes `recurrence_next_date`.
|
|
47
|
+
- **Archived tasks**: Have `archived_at` timestamp. Excluded by default; pass `includeArchived=true`.
|
|
48
|
+
- **GET detail** returns enriched data: `milestone`, `assignee`, `assignees`, `sub_tasks`, `issue_labels`, `isBlocked`.
|
|
49
|
+
|
|
50
|
+
**Bulk create** (`POST /issues/bulk`):
|
|
51
|
+
```json
|
|
52
|
+
{ "issues": [{ "title": "Task 1", "status": "todo", "priority": 1, "projectId": "..." }] }
|
|
53
|
+
```
|
|
54
|
+
Returns `{ issues: [...], count: N }` (201). Max 50 per request.
|
|
55
|
+
|
|
56
|
+
## Goal Fields
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"title": "Reach 100 paying customers by Q2",
|
|
61
|
+
"description": "Our primary growth objective",
|
|
62
|
+
"owner_id": "member-uuid",
|
|
63
|
+
"status": "active",
|
|
64
|
+
"target_date": "2026-06-30"
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## KPI Fields
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"name": "paying_customers",
|
|
73
|
+
"description": "Total active paying customers",
|
|
74
|
+
"goal_id": "goal-uuid",
|
|
75
|
+
"unit": "count",
|
|
76
|
+
"unit_label": "customers",
|
|
77
|
+
"target_value": 100,
|
|
78
|
+
"target_direction": "increase",
|
|
79
|
+
"source_type": "manual",
|
|
80
|
+
"stale_after_hours": 168
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## KPI Snapshots
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"value": 34,
|
|
89
|
+
"source": "agent",
|
|
90
|
+
"attribution_note": "Checked Stripe dashboard",
|
|
91
|
+
"attributed_to_initiative_id": "initiative-uuid",
|
|
92
|
+
"attributed_to_issue_id": "issue-uuid"
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Recording a snapshot auto-updates the KPI's `current_value`.
|
|
97
|
+
|
|
98
|
+
## Initiative Fields
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"title": "Launch self-serve onboarding flow",
|
|
103
|
+
"description": "Reduce friction for new signups",
|
|
104
|
+
"goal_id": "goal-uuid",
|
|
105
|
+
"owner_id": "member-uuid",
|
|
106
|
+
"status": "active",
|
|
107
|
+
"target_date": "2026-05-15"
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
For portfolio-style initiatives (grouping projects):
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"name": "Q2 Platform Rewrite",
|
|
115
|
+
"description": "Migrate all services to new architecture",
|
|
116
|
+
"owner_id": "member-uuid",
|
|
117
|
+
"start_date": "2026-04-01",
|
|
118
|
+
"target_date": "2026-06-30"
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Add/remove projects with `{ "project_id": "uuid" }`.
|
|
123
|
+
|
|
124
|
+
## Automation Rule Fields
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"name": "Auto-assign urgent bugs",
|
|
129
|
+
"trigger_event": "issue.created",
|
|
130
|
+
"conditions": [{ "field": "priority", "operator": "eq", "value": 0 }],
|
|
131
|
+
"actions": [{ "type": "set_assignee", "value": "member-uuid" }],
|
|
132
|
+
"enabled": true,
|
|
133
|
+
"project_id": "project-uuid"
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Dry-run test**: Send `{ "issue_id": "uuid" }` or `{ "issue": { "status": "todo", "priority": 2 } }`. Returns `{ matched, actions_that_would_run }`.
|
|
138
|
+
|
|
139
|
+
## Custom View Fields
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
{
|
|
143
|
+
"name": "My Sprint View",
|
|
144
|
+
"filters": { "status": ["in_progress", "todo"], "priority": [0, 1] },
|
|
145
|
+
"sort": { "field": "priority", "direction": "asc" },
|
|
146
|
+
"display_mode": "board",
|
|
147
|
+
"color": "#6B7280",
|
|
148
|
+
"icon": "list"
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`display_mode`: `board`, `list`. `filters` and `sort` are freeform JSON.
|
|
153
|
+
|
|
154
|
+
## Webhook Fields
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"url": "https://example.com/webhook",
|
|
159
|
+
"events": ["issue.created", "issue.updated"],
|
|
160
|
+
"enabled": true
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
URL must be HTTPS. Response includes `secret` for HMAC signature verification.
|
|
165
|
+
|
|
166
|
+
## Heartbeat Response
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"agent": { "id": "...", "display_name": "Growth Agent" },
|
|
171
|
+
"timestamp": "2026-03-29T12:00:00Z",
|
|
172
|
+
"goals": [{
|
|
173
|
+
"goal": { "id", "title", "status", "target_date" },
|
|
174
|
+
"days_remaining": 93,
|
|
175
|
+
"kpis": [{
|
|
176
|
+
"kpi": { "name", "current_value", "target_value" },
|
|
177
|
+
"pace_needed": 0.71,
|
|
178
|
+
"pace_actual": 0.42,
|
|
179
|
+
"trend": "accelerating",
|
|
180
|
+
"is_stale": false,
|
|
181
|
+
"is_off_pace": true,
|
|
182
|
+
"snapshots_recent": [...]
|
|
183
|
+
}],
|
|
184
|
+
"initiatives": [{
|
|
185
|
+
"initiative": { "title", "status" },
|
|
186
|
+
"expected_impacts": [{ "kpi_id", "expected_impact" }],
|
|
187
|
+
"total_issues": 8,
|
|
188
|
+
"completed_issues": 3,
|
|
189
|
+
"stalled_issues": 2,
|
|
190
|
+
"blocked_issues": 1
|
|
191
|
+
}]
|
|
192
|
+
}],
|
|
193
|
+
"standalone_kpis": [...],
|
|
194
|
+
"assigned_issues": [...],
|
|
195
|
+
"signals": [
|
|
196
|
+
{ "type": "kpi_off_pace", "severity": "warning", "message": "..." }
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Analytics Response
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"statusDistribution": [{ "status": "done", "count": 42 }],
|
|
206
|
+
"priorityBreakdown": [{ "priority": 1, "count": 15 }],
|
|
207
|
+
"assigneeWorkload": [{ "assignee_id": "...", "display_name": "...", "count": 8 }],
|
|
208
|
+
"dailyCounts": [{ "date": "2026-03-01", "created": 5, "completed": 3 }]
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Enums
|
|
215
|
+
|
|
216
|
+
| Domain | Field | Values |
|
|
217
|
+
|--------|-------|--------|
|
|
218
|
+
| Task | `status` | `backlog`, `todo`, `in_progress`, `done`, `cancelled` (custom per project via board-columns) |
|
|
219
|
+
| Task | `priority` | `0` (urgent), `1` (high), `2` (medium), `3` (low) |
|
|
220
|
+
| Task | `recurrenceType` | `daily`, `weekly`, `monthly`, `yearly` |
|
|
221
|
+
| Goal | `status` | `active`, `achieved`, `missed`, `paused`, `cancelled` |
|
|
222
|
+
| KPI | `unit` | `count`, `percentage`, `currency`, `duration`, `ratio`, `custom` |
|
|
223
|
+
| KPI | `target_direction` | `increase`, `decrease`, `maintain` |
|
|
224
|
+
| KPI | `source_type` | `manual`, `webhook`, `api_poll`, `formula` |
|
|
225
|
+
| KPI snapshot | `source` | `manual`, `webhook`, `api_poll`, `formula`, `agent` |
|
|
226
|
+
| Initiative | `status` | `proposed`, `active`, `completed`, `paused`, `cancelled` |
|
|
227
|
+
| Status update | `status` | `on_track`, `at_risk`, `off_track` |
|
|
228
|
+
| Member | `role` | `owner`, `admin`, `member`, `guest` |
|
|
229
|
+
| Project member | `accessLevel` | `view`, `edit`, `admin` |
|
|
230
|
+
| Automation | `trigger_event` | `issue.created`, `issue.status_changed`, `issue.assigned`, `issue.priority_changed` |
|
|
231
|
+
| Heartbeat signal | `type` | `kpi_off_pace`, `kpi_stale`, `issue_stale`, `issue_blocked`, `milestone_overdue`, `initiative_stalled`, `webhook_failing` |
|
|
232
|
+
| Heartbeat signal | `severity` | `info`, `warning`, `critical` |
|
|
233
|
+
| Custom view | `display_mode` | `board`, `list` |
|
|
234
|
+
|
|
235
|
+
## Response Format
|
|
236
|
+
|
|
237
|
+
All endpoints return JSON. Successful: `200` or `201`. Errors: `{ "error": "message" }` with `400`, `401`, `403`, `404`, `409`, or `500`.
|
|
238
|
+
|
|
239
|
+
List responses include `total`, `limit`, `offset` for pagination.
|
|
240
|
+
|
|
241
|
+
## Notes
|
|
242
|
+
|
|
243
|
+
- All timestamps are ISO 8601 in UTC
|
|
244
|
+
- Description and comment fields support Markdown
|
|
245
|
+
- Board columns (statuses) are customizable per project -- query `/board-columns` for available statuses
|
|
246
|
+
- Default statuses for new projects: `backlog`, `todo`, `in_progress`, `done`
|
|
247
|
+
- `cancelled` is always valid but not shown on the board
|
|
248
|
+
- Agent actions appear in the activity feed with the agent's name
|
|
249
|
+
- Changes via API appear in real-time on the web board
|