Docs Guide · updated October 09, 2026
Connect your product
Configure your source and a token
Create a source for your application in Account → API and exports → Id sources (for example
name Kitchnware, API name kitchnware). The API name is yours and stays fixed. Create a read-and-write
token for the integration. A token is not tied to a source: the address of each call says whose id it uses.
One id is one customer. A customer can hold several ids of your source: a company with two workspaces is one customer, and its usage is the sum of both.
Send each organization, with who pays
The libraries send it for you (gem "sumwerk", npm install sumwerk):
sumwerk.customers.upsert("kitchnware", org.id, name:, email:) in Ruby and
sumwerk.customers.upsert("kitchnware", org.id, { name, email }) in TypeScript make the call below.
PUT /api/v1/sources/kitchnware/customers/org_123
{"name":"Example Company","trial_started_at":"2026-09-24","stripe_customer_ids":["cus_Q2x…"],
"custom":{"company_type":"agency"}}
- Check
GET /api/v1/mefor the expected account and environment when the integration starts. - Send every organization once a day, and when something changes. Only supplied fields change;
customkeys merge, null removes a key. - Send the organization’s Stripe customer in
stripe_customer_ids. Stripe is the truth: a new organization whose Stripe customer sumwerk already holds joins that customer instead of becoming a duplicate. A Stripe customer that belongs to another customer is never moved; the answer carrieswarningsand a person merges the two in sumwerk if they are one company. - Keep the returned
idif you want to link to the customer in sumwerk. - Send the organization’s people to
POST /api/v1/sources/kitchnware/customers/org_123/contacts.
An organization that has not paid yet and that sumwerk only knows from somewhere else (a ChartMogul lead,
a booked call) can be attached first: find it (GET /api/v1/sources/chartmogul/customers/<uuid>), then
POST /api/v1/customers/<id>/external-references with {"source":"kitchnware","external_id":"org_123"}.
A retry of the same link is safe; an id that belongs to another customer returns 409 identity_conflict.
Send usage every day
PUT /api/v1/sources/kitchnware/usage/2026-09-23
{"customers":{"org_123":{"ads_launched":12,"active_users":3},"org_124":{"ads_launched":1}}}
One call per day for all organizations; leave out those that did nothing. Send the last three days
every night, so late data is corrected, and your history once as a backfill. Describe the metrics on
the Attributes page (name, unit, sum or level) and build your at-risk rules on their windows, for
example usage.ads_launched.change_28d_pct. Details in the API reference.
What your application sends is its own: an import from ChartMogul never overwrites those attributes, nor the name, company and trial dates of your organizations.
Ask what each organization may do (Billing)
With Billing set up (Set up billing), your application asks sumwerk what each organization may do, under the same source and ids:
GET /api/v1/billing/kitchnware/orgs/org_123
POST /api/v1/billing/kitchnware/usage
{"events":[{"event_id":"use_8842","org":"org_123","feature":"exports","quantity":1,"occurred_at":"2026-10-09T07:58:02Z"}]}
The answer names the plan, every feature, limit and rollout flag, and what was used. Changes come to
your webhook (Billing → Settings → Connection) or through GET /api/v1/billing/kitchnware?after_version=.
Each event_id counts once, so a batch can be sent again safely. The clients do all of this and keep the
answers in your own store: entitled?, allowed?, track, report. Fields, errors and what to retry:
API reference.
Update existing integrations
The old unscoped customer PUT returns 410. Customer responses no longer contain unlabelled
external_id/external_ids or ignored-write/primary/retired fields. Contact/note/task external ids
remain supported for their own retries. See the API reference for fields and errors. Retry
transient failures with bounded backoff and respect Retry-After; authentication, validation and
mapping conflicts need correction.