Skip to Content
Your subscription data now goes where you need it: the Curobi Developer API feeds your warehouse, ERP or CRM, and webhooks tell you the moment something changes — read the API docs →
Developer APIOverview

Developer API

Curobi has an HTTP API for pulling your subscription data into whatever else you run — a warehouse, an ERP, a CRM, a BI dashboard, a nightly reconciliation script — for changing a subscription from your own server, and signed outbound webhooks so those systems are told when something happens instead of polling for it.

https://app.curobi.com/api/admin/v1

The Developer API and outbound webhooks are a Pro feature, and they share one entitlement — the API is what you ask, webhooks are what you’re told, and a merchant with one and not the other has half an integration. See Pricing & Plans.

Quickstart

Confirm you’re on Pro

The API is checked against your plan on every request, not just when the key is minted. A key from a shop on any plan below Pro is refused with plan_upgrade_required even if the key itself is perfectly valid. Partner development stores are refused too, until the store is on a paid Shopify plan and Curobi Pro.

Mint a key

In your Curobi admin, open API keys, name the key after the system that will use it, and tick only the scopes that system needs.

write:subscriptions is off by default and ticking it raises a warning: it lets the holder cancel any contract on the shop. A reporting job never needs it.

The key is shown once. It’s stored as a salted hash and is not recoverable — if you lose it, revoke it and mint another.

Call the API

Every read is a plain HTTPS GET with one header, so any HTTP client will do. Writes add a second header — see subscription writes.

curl -sS "https://app.curobi.com/api/admin/v1/subscriptions?status=ACTIVE&limit=100" \ -H "Authorization: Bearer $CUROBI_API_KEY"

Every list endpoint answers with the same two-key envelope:

{ "data": [ { "contract_id": "gid://shopify/SubscriptionContract/1234", "status": "ACTIVE" } ], "next_cursor": "eyJ0IjoiMjAy…" }

Every tab above reads the key from the server’s environment, and that is the point. A secret key reads every subscription on the shop, and one holding write:subscriptions can cancel any of them — it must never reach a browser bundle, a mobile app, a theme file or a committed .env. The browser-safe credential is the publishable key (curobi_pk_…) on the Storefront API; a secret key presented there is refused, and a publishable key presented here is refused with invalid_credential.

Register a webhook endpoint

So you stop polling. Either from the Webhooks page in your Curobi admin, or over the API with a manage:webhooks key — see Webhooks.

What exists today

SurfaceStatusWhat it does
Admin API — /api/admin/v1✅ AvailableServer-to-server reads over subscriptions, plans, bundles, Mix & Match, gifts, win-back, notifications and analytics, behind a secret key
Subscription writes — /api/admin/v1/subscriptions/{id}/…✅ AvailablePause, resume, cancel, skip, reschedule and line edits under write:subscriptions, each requiring an Idempotency-Key — see subscription writes
Outbound webhooks✅ AvailableFifteen signed lifecycle events pushed to your endpoint, with retries and a delivery log
Headless purchase path✅ AvailableNeeds no Curobi credential at all — see Headless & custom storefronts
Export jobs — /api/admin/v1/exports✅ AvailableAsynchronous CSV and JSONL exports as jobs: ask, poll, fetch a signed download
Storefront API — /api/storefront/v1✅ AvailableBrowser-safe reads on a publishable key: the Mix & Match catalogue, a live price preview, and the selling_plan_id a cart line needs
Customer API — /api/customer/v1✅ AvailableA headless customer portal — the shopper’s Shopify customer token, exchanged for a Curobi session
Reference React components✅ AvailableEleven fork-and-restyle components for the headless purchase path and portal, including cart-line property helpers
Plan, bundle, Mix & Match, gift and win-back writesNot builtwrite:plans, write:bundles, write:mixmatch, write:gifts and write:winback are published vocabulary, not working endpoints. They are not offered when you mint a key

v1 is otherwise read-only, with three exceptions, in order of how much they can break.

  1. Subscription writes under write:subscriptions. These change a merchant’s own data and move money, so they carry obligations nothing else on this surface does: a mandatory Idempotency-Key, a tenancy check against contracts Curobi created, and a receipt rather than the resource.
  2. Webhook endpoint management under manage:webhooks — the API’s own plumbing, so a key that can start and stop event delivery still cannot change a contract, a plan or a price.
  3. POST /exports, a write in HTTP grammar only: it queues a read of rows the same key could already page through, and demands exactly the read scopes that paging would.

Everything else answers 405 method_not_allowed to a POST, PUT, PATCH or DELETE — after authenticating, so an unauthenticated probe still gets a 401 and learns nothing about which paths exist.

Two limits worth knowing before you design around them

Curobi can only see contracts Curobi created. The app holds Shopify’s read_own_subscription_contracts / write_own_subscription_contracts scopes, so a subscription another app created is invisible to this API even on a store where Curobi is installed. This is a Shopify permission boundary, not a Curobi decision. To bring old subscriptions across, use the CSV import, which creates real Curobi-owned contracts.

The data is a mirror, not the ledger. Every value the API returns is Curobi’s local copy of what Shopify last said. Shopify owns the contract and the money. Reconcile against Shopify before you bill anything against these figures.

Conventions at a glance

  • Versioning is in the path (/v1) and additive-only. New fields may appear; existing fields never change meaning and are never removed. Parse defensively — an unknown field is not an error.
  • Rate limits are per shop: 60 requests/minute sustained, burst 120.
  • Request ids (X-Curobi-Request-Id) are on every response. Quote one in a support request and we can find the exact call.
  • Protected Customer Data — names, email addresses and gift messages — comes back only to a key holding read:customers, and never over webhooks at any scope.
Last updated on