Skip to content

Custom integration

A custom integration is how your own code sends data to Summerbase. It is a source: everything your code sends is recorded as coming from it, under its own slug. It does one of two jobs:

  • Add details to customers your billing system already sent. Your billing is in Stripe, say, but your own system knows more: the plan tier in your product, the account manager, the industry. Your code adds that to the customers Stripe reported.
  • Send your subscriptions. Your billing runs on a system Summerbase doesn’t connect to, or on your own. Your code sends customers and their subscriptions, and Summerbase works out your metrics from them.

Both start the same way.

  1. Create the integration. Go to Settings, then Integrations, choose Add integration, then Custom. Give it a name and a short slug, such as backend. The slug can’t be changed later, because your records are named with it: your customer acct_4821 becomes backend:acct_4821 in Summerbase, and your code uses that id to address it.
  2. Create an API key. On the integration’s page, under API keys, choose New key. Copy the secret straight away: it’s shown only once. Keep it on your server. Everything the key sends is recorded as coming from this source, which is why an API key has a source_id.

Add details to customers from another source

Section titled “Add details to customers from another source”

Address the customer by your own id, and list the id your billing system uses for them under identities. That links the two, and your properties land on the same customer:

Terminal window
curl https://api.summerbase.com/v1/customers/backend:acct_4821 \
-X PATCH \
-H "Authorization: Bearer $SUMMERBASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"identities": ["stripe:cus_NfJG2nK3"],
"properties": {
"account_manager": "Dana Okafor",
"industry": "Logistics"
}
}'

From then on, either id finds the customer. Your properties are kept under your source, separately from Stripe’s, so neither overwrites the other: the API shows them as properties_by_source.backend next to properties_by_source.stripe. For promoted fields such as the name and email, a custom integration’s value beats Stripe’s by default. See How your data fits together.

You can add properties to a subscription the same way, addressed by the id Stripe has for it:

Terminal window
curl https://api.summerbase.com/v1/subscriptions/stripe:sub_1QxR8t \
-X PATCH \
-H "Authorization: Bearer $SUMMERBASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"properties": {"sales_channel": "partner"}}'

The subscription’s amounts, status and dates stay with its owner source, Stripe here. If Stripe hasn’t sent the subscription yet, the request is refused; send it again later.

Address each customer by your own id. Summerbase creates the customer the first time, and updates it after that.

Terminal window
curl https://api.summerbase.com/v1/customers/backend:acct_4821 \
-X PATCH \
-H "Authorization: Bearer $SUMMERBASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"name": "Northwind Labs",
"email": "billing@northwind.example.com"
}
}'

A subscription is on a price, and every price is on a plan, so both have to exist before a subscription names them. See Plans and prices.

First the plan, addressed by your own id for it. Summerbase creates it the first time, and updates it after that:

Terminal window
curl https://api.summerbase.com/v1/plans/backend:growth \
-X PATCH \
-H "Authorization: Bearer $SUMMERBASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"name": "Growth",
"archived": false
}
}'

Then each price on it, naming the plan with plan_id. A name and the price’s list terms are optional:

Terminal window
curl https://api.summerbase.com/v1/prices/backend:growth_monthly \
-X PATCH \
-H "Authorization: Bearer $SUMMERBASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"plan_id": "backend:growth",
"name": "Growth monthly",
"currency_code": "USD",
"interval": "month",
"interval_count": 1,
"pricing_model": "fixed",
"unit_amount": "50.00"
}'

An annual Growth price is a second price with the same plan_id.

Each item names its price with price_id. The plan comes from the price.

Terminal window
curl https://api.summerbase.com/v1/subscriptions/backend:sub_311 \
-X PATCH \
-H "Authorization: Bearer $SUMMERBASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"claim_ownership": true,
"customer_id": "backend:acct_4821",
"status": "active",
"currency_code": "USD",
"items": [
{
"id": "backend:item_9001",
"price_id": "backend:growth_monthly",
"unit_amount": "50.00",
"quantity": "25",
"interval": "month"
}
]
}'

claim_ownership: true is needed the first time you send a subscription. It makes your source the subscription’s owner source (owner_source_id in the API): the one it’s billed through. From then on, only your source can change its amounts, status and dates.

The order matters: plans, then prices, then subscriptions. A subscription that names a price Summerbase doesn’t have yet is refused as a whole.

Whenever something changes, such as a move to another price, more seats or a cancellation, send the subscription again with what’s true now. A new price goes in before the first subscription on it. Sending the same thing twice is harmless.

To load the history you had before using Summerbase, see Reimport subscription.

The API reference has every endpoint and field.

If you’re an AI agent writing this integration for someone:

  • The API reference explains every endpoint, with examples.
  • The OpenAPI spec, https://api.summerbase.com/v1/open_api, has every endpoint’s exact request and response, to check a call against or generate a client from.
  • Read the integration’s key from the person’s environment or secrets. Don’t ask them to paste it into the chat.