For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
my.pivotal.appGet an API key
Get StartedGuidesAPI ReferenceSDKsChangelog
Get StartedGuidesAPI ReferenceSDKsChangelog
  • Common workflows
    • Create your first customer
    • Onboarding phases
    • Integration sync
    • display_id vs id
    • Bulk operations
    • Test mode
LogoLogo
my.pivotal.appGet an API key
On this page
  • The phase transition flow
  • Driving an onboarding end to end
  • Combining phase + state
  • What you shouldn’t do
  • Querying by phase
  • Hooking into Pivotal automations
Common workflows

Onboarding phases

Move an onboarding through the lifecycle.
|View as Markdown|Open in Claude|
Was this page helpful?
Edit this page
Previous

Create your first customer

Next

Integration sync

Built with

An onboarding’s phase represents where the engagement sits in the Pivotal workflow. The full enum, in order:

PhaseWhat it means
before_getting_startedContract signed, intro call scheduled, nothing’s started yet.
program_designRequirements gathering, mockups, program scoping.
reviewDesign review and customer sign-off on the program.
program_buildoutImplementation underway.
internal_qaPre-launch testing by the Pivotal team.
launchLive.
completedHand-off to ongoing CS. Terminal.

The state field is separate and tracks engagement health: active, paused, at_risk, waiting. A phase is “where we are”; a state is “is anything blocking”.

The phase transition flow

PATCH /onboardings/{id} changes one or many fields at once. Phase transitions are the most common pattern:

$curl -X PATCH https://my.pivotal.app/api/v1/onboardings/89 \
> -H "Authorization: Bearer $PIVOTAL_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{"phase": "program_design"}'

Every phase change writes two records on the Pivotal side:

  1. A timeline event on the underlying customer — surfaces on the customer page.
  2. A phase transition row — feeds the SLA reports inside Pivotal.

The actor on both is the calling API key’s name. Nothing in your code needs to do anything extra to get audit coverage.

Driving an onboarding end to end

Here’s a script that walks an onboarding through every phase, pausing briefly between steps:

advance-onboarding.ts
1const API = "https://my.pivotal.app/api/v1";
2const KEY = process.env.PIVOTAL_API_KEY!;
3const ID = process.argv[2]; // pass onboarding display_id or cuid
4
5const phases = [
6 "before_getting_started",
7 "program_design",
8 "review",
9 "program_buildout",
10 "internal_qa",
11 "launch",
12 "completed",
13];
14
15async function setPhase(phase: string) {
16 const res = await fetch(`${API}/onboardings/${ID}`, {
17 method: "PATCH",
18 headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
19 body: JSON.stringify({ phase }),
20 });
21 const body = await res.json();
22 if (!res.ok) throw new Error(`${res.status} ${body.error?.code}`);
23 console.log(`→ ${phase} (updated_at=${body.updated_at})`);
24}
25
26for (const phase of phases) {
27 await setPhase(phase);
28 await new Promise((r) => setTimeout(r, 1000));
29}

Run it on a test onboarding. Refresh the customer page in Pivotal — the timeline shows each transition.

Combining phase + state

When an onboarding stalls, set state to paused, at_risk, or waiting without changing the phase:

$curl -X PATCH https://my.pivotal.app/api/v1/onboardings/89 \
> -H "Authorization: Bearer $PIVOTAL_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{"state": "at_risk"}'

When it un-sticks, set state back to active:

$curl -X PATCH https://my.pivotal.app/api/v1/onboardings/89 \
> -H "Authorization: Bearer $PIVOTAL_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{"state": "active"}'

Separating “where we are” from “is anything wrong” keeps the phase progression clean and the SLA reporting honest.

The waiting state is special: combined with waiting_on_customer: true, it tells Pivotal a customer task is blocking, which suspends the SLA clock until the state flips back.

What you shouldn’t do

  • Don’t skip phases for cosmetics. Pivotal computes phase-duration metrics — jumping before_getting_started → launch reads as “this onboarding launched in 4 days” in dashboards.
  • Don’t reuse completed for anything else. It’s the terminal phase. Use state: "paused" to retract a launch, or DELETE to soft-delete a wrong record.
  • Don’t PATCH phase on a soft-deleted onboarding. You’ll get 404 onboarding_not_found.

Querying by phase

GET /onboardings?phase=launch filters by phase. Combine with state:

$curl "https://my.pivotal.app/api/v1/onboardings?phase=launch&state=active&limit=50" \
> -H "Authorization: Bearer $PIVOTAL_API_KEY"

Combined with cursor pagination (Pagination), this is enough to build a dashboard that polls “what’s in launch this week”.

Hooking into Pivotal automations

When phase flips to launch, Pivotal fires its built-in launch-day automations: a Slack DM to the assigned CSM, a launch entry in the customer calendar, and (if the workspace has it enabled) an auto-drafted launch-recap email. These run inside Pivotal regardless of whether the phase change came from the UI or the API.

If you want to suppress those — say, you’re backfilling historical onboardings — make the calls with a test key (pivotal_test_…). See Test mode.