Skip to content

Update the current project

PATCH
/v1/project
curl -X PATCH "https://api.summerbase.com/v1/project" \
-H "Authorization: Bearer sb_..." \
-H "Content-Type: application/json" \
-d '{
"reporting_currency_code": "USD",
"reporting_timezone": "America/New_York"
}'

Rename the project, or move its slug.

Renaming does not move the slug: the two are separate, and a slug is an address. Moving it changes every URL the project is reachable at, and the old one stops resolving immediately — anything that stored it, a bookmark or an integration sending Summerbase-Project, breaks. Nothing reserves the slug you leave behind.

Changing a setting that decides how the project is measured recomputes every customer in it, and every number moves as it goes. There is a limit on how often that may be asked for.

expand[]
Array<string>
<= 10 items
Allowed values: organization reporting_currency

Relationships to include in the response instead of fetching separately. A dotted path expands what an expanded record can expand in turn — at most 4 deep, 10 paths a request, and never back to a record already on the path.

Media typeapplication/json
object
churn_timing

When a subscription’s revenue stops counting: at_expiration, when it ends, or at_cancellation, when a cancellation is booked for it.

Under at_cancellation a subscription with cancels_at set is worth nothing from the moment the source said so, though it is still in service: the customer’s MRR drops then, the movement is churn, or contraction if something else is still live, and a customer with nothing else live is churned. Withdrawing the cancellation brings the revenue back. A trial booked to end loses nothing, having nothing to lose. A Stripe import dates a booking at Stripe’s canceled_at, which holds only the latest request, so an earlier or withdrawn one is not in the history.

Changing it moves the metrics of every customer in the project.

string
Allowed values: at_expiration at_cancellation
movement_collapse_window_days

How close together two changes to a customer’s revenue have to be to count as one.

Signing up at $100 and upgrading to $500 the next day is $500 of new revenue, not $100 of new plus $400 of expansion, and a cancellation reversed within the window is neither a churn nor a reactivation. The collapsed movement is dated at the first change in the window, so a customer who arrives on the 30th and upgrades on the 2nd still arrived in the first month. 0 records every change as it happened.

An elapsed duration, not a calendar one: seven days is 168 hours wherever the project reports from. Changing it moves the metrics of every customer in the project, and a closed period can move while it is still inside the window.

integer
<= 90
name

What the project is called.

string
>= 1 characters <= 255 characters
reporting_cadence

Which cadence the project quotes its metrics at: monthly, MRR, or annual, ARR.

Every measure is answered at either cadence whatever this says. What it decides is which of the two Summerbase shows where it shows one.

string
Allowed values: monthly annual
reporting_currency_code

The currency every amount is reported in, by its ISO 4217 code. A project’s first import sets it to the currency most of the imported subscriptions are billed in, and nothing changes it afterwards but this action.

Amounts are converted at the rate for the moment being measured, so a project billing in three currencies has one number to look at.

string
>= 3 characters <= 3 characters
reporting_timezone

The timezone every chart’s buckets are cut in, by its IANA name — Europe/Copenhagen, America/New_York, UTC — as /v1/timezones lists them. An offset like +02:00 and an abbreviation like CET are refused.

It decides which day a midnight-adjacent event falls in, and where a month starts.

string
slug

How the project is addressed in a readable URL — the production in app.summerbase.com/projects/production@acme, or that one slug alone when it is the organization’s too. Lowercase letters, digits, hyphens and underscores, and never shaped like an id.

Unique within the organization: one already used there is refused. Derived from the name when you do not choose one. Changing it is allowed and breaks every address that used the old one.

string
>= 1 characters <= 100 characters

Example

{
"reporting_currency_code": "USD",
"reporting_timezone": "America/New_York"
}

Returns the project object.

Media typeapplication/json

Example

{
"checklist_dismissed_at": null,
"churn_timing": "at_expiration",
"created_at": "2025-09-08T14:02:37Z",
"id": "0198f1a2-6c52-7b18-8e3f-2a9c4d6b1e07",
"movement_collapse_window_days": 7,
"name": "Production",
"object": "project",
"organization_id": "0198f1a2-6c3d-7e41-9a2b-5c8d1e4f7a90",
"recompute_failed_at": null,
"recompute_remaining": 0,
"recompute_started_at": null,
"recompute_total": 0,
"reporting_cadence": "monthly",
"reporting_currency_code": "USD",
"reporting_timezone": "America/New_York",
"slug": "production"
}