Skip to main content

Planning for integrators and assistants

What this page is — Every way software, rather than a person at the Planning screen, reaches the plan: the Orbit Public API, the planning.committed webhook, the MCP tools an AI agent uses, the client SDKs, and the questions the Orbit Assistant can answer about plans, capacity and hires. What it is for — Feeding the committed sprint plan into a BI tool, a resourcing system or a status page; preparing scenarios and planned hires from a recruiting or portfolio tool; and letting people ask "which sprints are over capacity?" in plain language. The problem it solves — A plan that lives only on one screen gets copied into spreadsheets by hand and is stale the day after. These interfaces read the same plan the screen shows, so other systems stay current without anyone re-typing it — while the one decision that changes real tasks, the commit, stays with a person in the app.


Base path: /api/v1/ext/task/planning · Credentials: an API key from Developers → API keys carrying the Planning scopes below · Assistant: needs View planning Module: Planning · Entry points: the developers portal (developers.<your-domain> — Orbit Ops → Planning) · Developers → Webhooks · the Orbit Assistant · Ask AI in the Planning header


1. What is available, and to whom​

InterfaceDirectionWho uses itReadsWrites
Public APIYour system → OrbitIntegrations with an API keyTree, committed plans, burndown, scenarios, commits, planned hires, task planning fieldsDraft scenarios, planned hires, task planning fields
Webhook planning.committedOrbit → your systemIntegrations subscribed on Developers → Webhooks—— (a notification)
MCP toolsAn AI agent → OrbitAgents connected with an API keySame as the APISame as the API
Client SDKsYour code → OrbitTypeScript and Python developersSame as the APISame as the API
Orbit AssistantA person → OrbitAnyone with View planningSummary, time boxes, one sprint, scenarios, commits, hiresNothing

What is deliberately not exposed. Committing a scenario rewrites many tasks at once — sprint, assignee, estimates — and notifies people. It is a human decision taken in the app with its preview, so no API, MCP tool, SDK method or assistant question can commit. The same goes for the board moves inside a scenario, drift and rebase, Compare, Suggest with AI and the AI goal check: an integration prepares the inputs (a scenario, a hire, task estimates) and reads the outcome, and subscribes to planning.committed to learn when a person committed.


2. Why you would use it​

  • Report on plans without exporting. A BI tool reads committed capacity, committed hours and the burndown every night, so the portfolio dashboard is never a week old.
  • Keep hiring and planning in step. When a requisition opens in your recruiting system, create the planned hire in Orbit with its hours and start date; planners can put work on it the same day.
  • React to a commit. The webhook tells a status page, a chat channel or a finance system the moment a sprint plan is locked in, with counters of what changed.
  • Answer questions in seconds. The assistant answers "is the next sprint on track?" from the committed plan, for free, without anyone opening Planning.

3. Step by step — connect an integration​

  1. Developers → API keys — create a key and tick task:planning:read (and task:planning:write if the integration creates scenarios or hires). Existing keys do not gain these scopes automatically; edit the key to add them. Bind the key to one project if the integration should only ever see that project.
  2. Send the key on every call — X-Orbit-API-Key: <key> or Authorization: Bearer <key>.
  3. Call GET /tree to learn the project's phases, sprints and milestones. A SPRINT or PHASE id is a time box id; a MILESTONE id is what a task contributes to.
  4. Read a sprint: GET /timeboxes/{id}/plan for the committed plan, GET /timeboxes/{id}/burndown for the daily series.
  5. On POSTs, send an Idempotency-Key header, unique per logical operation, so a retry never creates a second scenario or hire.
  6. Developers → Webhooks — add your endpoint and tick planning.committed in the Orbit Ops – Planning group.

The organisation, and the project for a project-bound key, always come from the key. An org-wide key passes project_id as a query parameter on project-level calls.


4. Field reference​

Scopes​

ScopeAllows
task:planning:readRead planning: committed time-box plans and capacity, burndown, scenarios, commits and planned hires
task:planning:writeCreate planning scenarios and planned hires (never writes tasks)

The ten endpoints (prefix /api/v1/ext/task/planning)​

Method and pathScopeWhat it returns or does
GET /treereadphases with their child sprints and milestones, plus orphans; each node carries its committed plan summary (or null), open and done task counts and date warnings (sprint_outside_phase, sprint_overlap, phase_outside_project, milestone_outside_phase)
GET /timeboxes/{id}/planreadThe committed plan of a sprint or phase: goal, success criteria, per-person capacity rows with names, committed hours, points and tasks, hire capacity, last goal-check verdict. 404 no_plan when nothing was committed; 422 for a MILESTONE id
GET /timeboxes/{id}/burndownreadDaily snapshots oldest first, the ideal line, and a live today point. Query days (0–3650, 0 = all)
GET /scenariosreadScenario summaries, newest first. Query status — any of draft, committed, archived; default draft,committed
POST /scenarioswriteSeeds a draft scenario. Body: name (required, unique in the project — 409 name_taken otherwise), timebox_ids (required, at least one SPRINT or PHASE id; a phase pulls its sprints in), notes, include_backlog (default true). Nothing about any task changes
GET /scenarios/{id}readOne scenario summary: status, time boxes, drift flag and count, item count, who created and who committed
GET /commitsreadCommit summaries, newest first. Query limit 1–200, default 20
GET /commits/{id}readOne commit with every task field it wrote (diffs), the warnings that were accepted, and the capacity and goals it committed
GET /virtual-resourcesreadPlanned hires. Query status — any of active, hired, cancelled; default active,hired. A project-bound key sees only hires linked to its project
POST /virtual-resourceswriteCreates a planned hire. Body: name (required), role_text, skills, hours_per_week (0–168, default 40), zone_id, available_from / available_to (YYYY-MM-DD, end not before start), notes, project_ids. Never assigns tasks

Task and milestone planning fields​

The task and milestone endpoints of the Orbit Ops API carry the planning vocabulary:

WhereFieldMeaning
Task (create, update, read)milestoneThe task's time box — a SPRINT or PHASE id. A MILESTONE id sent here is stored as target_milestone_id instead
Task (create, update, read)target_milestone_idThe MILESTONE the task contributes to; another type answers 422 target_must_be_milestone; null clears
Task (create, update, read)story_pointsSize in points (0–99999). When estimated_hours is omitted it is derived from the project's size scale
Task (read only)estimate_sourcepoints when the hours were derived from points, otherwise manual
Task (read only)planned_resource_idThe planned hire the work was committed to while nobody is assigned; set only by a commit
Task list filterstimebox_id · target_milestone_idComma-separated ids, exact match
Milestone (read)type · parent_idPHASE, SPRINT or MILESTONE; the phase a sprint or milestone belongs to
Milestone (read)goal · plan_statusThe committed goal, and committed when a plan was committed for that box

A change that breaks the project's date rules answers 422 with the rule's code, the same rule the Roadmap enforces.

Webhook planning.committed​

Sent once after every successful commit made in the app. The payload:

FieldMeaning
commit_idRead the full commit with GET /commits/{commit_id}
scenario_id · scenario_nameThe scenario that was committed
project_idThe project
committed_byThe user who pressed Commit
summaryCounters: tasks_changed, moved, reassigned, re_estimated, hires_assigned, timeboxes, net_capacity_hours, committed_hours

Delivery, signing and retries work exactly as for every other Orbit webhook configured under Developers → Webhooks.

MCP tools​

An agent connected to the Orbit MCP server with a key carrying the Planning scopes sees ten tools, one per endpoint:

ToolEndpointScope
get_planning_treeGET /treeread
get_planning_timebox_planGET /timeboxes/{id}/planread
get_planning_timebox_burndownGET /timeboxes/{id}/burndownread
list_planning_scenariosGET /scenariosread
create_planning_scenarioPOST /scenarioswrite
get_planning_scenarioGET /scenarios/{id}read
list_planning_commitsGET /commitsread
get_planning_commitGET /commits/{id}read
list_planning_virtual_resourcesGET /virtual-resourcesread
create_planning_virtual_resourcePOST /virtual-resourceswrite

A tool whose scope the key lacks is simply not offered to the agent.

SDK methods​

Both reference clients on the developers portal group Planning under the task namespace:

EndpointTypeScript (client.task.…)Python (client.task.…)
GET /treeplanningTree()planning_tree()
GET /timeboxes/{id}/plantimeboxPlan(timeboxId)timebox_plan(timebox_id)
GET /timeboxes/{id}/burndowntimeboxBurndown(timeboxId, { days })timebox_burndown(timebox_id, days=None)
GET /scenarioslistScenarios({ status })list_scenarios(status=None)
GET /scenarios/{id}getScenario(id)get_scenario(scenario_id)
POST /scenarioscreateScenario(body)create_scenario(body)
GET /commitslistCommits({ limit })list_commits(limit=None)
GET /commits/{id}getCommit(id)get_commit(commit_id)
GET /virtual-resourceslistPlannedHires({ status })list_planned_hires(status=None)
POST /virtual-resourcescreatePlannedHire(body)create_planned_hire(body)

Project-level methods also accept a project id for org-wide keys; the Python create methods accept an idempotency_key.

Orbit Assistant — questions and the tools behind them​

The assistant (and the voice assistant, which shows checking planning, reading sprint capacity and similar while it works) answers from six read-only tools. All are free, need View planning, and only read projects you are a member of.

Ask something likeToolWhat comes back
"How is planning looking?" · "Any overcommitted sprints?"planning.summaryActive and overcommitted time boxes, commits in the last 7 days, draft and drifted scenarios, active hires, tasks waiting on a hire, and the sprint ending soonest with its load against capacity
"Which sprints are over capacity?" · "What sprints are running?"planning.timeboxesActive and upcoming sprints and phases with committed goal, net capacity, open load, ratio, state and days left
"Is Sprint 14 on track?" · "Who has spare capacity in Sprint 14?"planning.timebox.getOne sprint or phase by name: goal and criteria, each person's and hire's capacity against load and spare hours, the last goal-check verdict and the last 7 burndown points. It never runs a new goal check
"What planning scenarios do we have?"planning.scenariosName, status, drift and its count, item count, last update, who committed and when
"Who committed the last plan and what changed?"planning.commitsRecent commits with their counters and warnings
"Which hires are we planning?"planning.hiresThe organisation's planned hires: role, skills, hours, window, status, who replaced them, linked projects, and open tasks still waiting on each

The Ask AI button in the Planning header offers three of these as starters.


5. Worked example​

A company runs its recruiting in an applicant-tracking system and its portfolio reporting in a BI tool.

  1. When the ATS opens the requisition Backend dev #2, a small job calls POST /api/v1/ext/task/planning/virtual-resources with name: "Backend dev #2", role_text: "Senior Go engineer", hours_per_week: 40, available_from: "2026-10-01", project_ids set to the Checkout project, and an Idempotency-Key of the requisition number. The planner sees the hire under Link existing hire within seconds and plans four tasks on it in the scenario Q4 — hire two backend devs.
  2. On Friday the planner commits. Orbit sends planning.committed with scenario_name: "Q4 — hire two backend devs" and summary.hires_assigned: 4. The integration posts a message to the delivery channel and calls GET /commits/{commit_id} to store the diffs.
  3. Every night the BI tool calls GET /tree, then GET /timeboxes/{id}/plan and GET /timeboxes/{id}/burndown?days=14 for each active sprint, and charts committed hours against net capacity across all projects.
  4. On Monday the delivery lead asks the assistant "Is Sprint 14 on track?". It calls planning.timebox.get and answers that Sprint 14 is at 96% of net capacity, the goal check from Thursday said on track, and one engineer has 6 hours spare.
  5. When the hire signs, the ATS cannot replace the hire — that stays a planner's action in the Capacity grid (Replace with real user…) — so the job posts a reminder to the planner instead.

6. The admin contract​

  • Keys need the scopes explicitly. Keys created before Planning existed never gain task:planning:read or task:planning:write on their own.
  • A project-bound key sees only its project's plan, and only the hires linked to that project; it can link a new hire to its own project only.
  • Webhook subscriptions are per event: tick planning.committed under Orbit Ops – Planning on each endpoint that should receive it.
  • The assistant follows the user's permissions, not a key: without View planning it declines planning questions.
  • Rate limits and idempotency follow the Orbit Public API defaults described on the developers portal.

7. Don't confuse this with…​

  • Scenarios and commit — where a person moves tasks, runs Suggest with AI and commits. None of that is available through the API.
  • Delivery forecast — has its own endpoint and scope (task:risk:read); the Planning scopes do not include it.
  • The Plan committed notification — a bell alert and email to the project's managers and leads. The webhook is the machine-readable equivalent for other systems.

8. Troubleshooting​

SymptomCauseFix
403 on every Planning callThe key lacks task:planning:readEdit the key and add the scope
404 no_plan from /timeboxes/{id}/planNothing has been committed for that sprint yetRead /tree — plan is null there too; wait for a commit
422 from /timeboxes/{id}/planThe id is a MILESTONE, not a sprint or phaseUse a SPRINT or PHASE id from /tree
409 name_taken creating a scenarioA scenario with that name already exists in the projectChoose another name, or read the existing one
A created hire does not appear on the Capacity gridThe hire is linked to the project but not yet added to the scenarioThe planner uses Link existing hire → Add to scenario
No planning.committed deliveriesThe endpoint is not subscribed to the event, or nobody has committedTick the event on Developers → Webhooks; check the commit history on the Live tab
The agent does not list any planning toolsThe MCP key lacks the Planning scopesAdd them to the key and reconnect the agent
The assistant reports no capacity or goal for a busy sprintThe sprint was planned on the live board and never committed, so it has no committed capacity or goalCommit a scenario that includes it