Skip to content

Update Lifecycles

PUT
/revenue/lifecycle

REPLACE the whole set of Revenue lifecycle stages.

Not a merge. The posted entries array becomes the config, so a stage left out of it is DELETED along with the document defaults attached to it. Read GET /lifecycle-stages first and send the full list back with your change applied.

An entry with an empty id is treated as NEW and gets a fresh UUID. An entry that keeps its id keeps its stage document defaults - those are merged forward by id, not rebuilt.

Authorizations

Parameters

Header Parameters

X-Target-Org-Id
Any of:
string

Request Body required

REPLACES the whole entries array. A stage left out is DELETED.

This is a PUT in the app and a PUT here for that reason: it is not a merge. Read GET /lifecycle-stages first and send the full list back with your change applied.

object
entries
required
Array<object>

One Revenue lifecycle stage.

id is REQUIRED and may be the empty string: the app assigns a fresh UUID to any entry that arrives without one, which is how a new stage is created. Mirrored as required-but-emptyable rather than optional so the field cannot be omitted by accident on an entry that was meant to be an UPDATE - a missing id there does not fail, it silently creates a duplicate stage and orphans the original’s documents.

object
auto_hide_if_empty
boolean
default: true
churn_reason_categories
Any of:
Array<string>
custom_status_match
Array<string>
description
Any of:
string
event_tracking
Any of:
object
enabled
boolean
events
Array<object>

One tracked platform event configured against a lifecycle stage.

object
bucket
required

Activation | usage | expansion | risk | aha_moment

string
description
Any of:
string
<= 240 characters
display_name
required
string
>= 1 characters <= 80 characters
event_name
required
string
>= 1 characters <= 80 characters
path_to_paid_step
Any of:
integer
<= 50
weight
Any of:
number
<= 100
hidden
boolean
icon
string
default: Target
id
required
string
is_system_seed
boolean
name
required
string
>= 1 characters <= 64 characters
plan_tier_filter
Any of:
Array<string>
slug
required
string
>= 1 characters <= 64 characters
sort_order
integer
status_match
Array<string>
subscription_filter
Any of:
Array<string>

Responses

200

Successful Response

object
data
required

An OPEN envelope around one report’s answer.

The app wraps every one of these reports in {success, data, meta}, where meta carries the cache state, the window and - on the agency reports - failed_org_ids, the orgs that contributed NOTHING to the totals above. That field is the difference between “this client sent no email” and “we could not query this client”, so it is forwarded rather than flattened away.

Open on purpose: data is dict | list in the app and its contents grow with the product. A closed model would turn every new metric into a silently dropped one.

object
key
additional properties
any
pagination
Any of:
object
has_next
required

Whether there are more pages

boolean
limit
required

Items per page

integer
next_cursor
Any of:
string
notes
Any of:
Array<string>
page
required

Current page number (1-indexed)

integer
total
required

Total number of items

integer
total_available
Any of:
integer
total_is_lower_bound
Any of:
boolean

422

Validation Error

object
detail
Array<object>
object
loc
required
Array
msg
required
string
type
required
string