Gorgias
Connect Gorgias and every ticket shows a card in the right-hand sidebar with the customer’s Curobi subscriptions: status, products, how often each one bills, the next charge date, the amount and the order it started from. On each subscription sit five buttons: Skip next order, Pause, Resume, Reschedule and Cancel. When a customer writes in to skip a box, the agent answering the ticket does it there, without opening Curobi or the Shopify admin.
Available on the Pro plan, on a paid Shopify plan. The card runs on Curobi’s Admin API, which is part of Pro and stays off on development stores. On the Gorgias side, the features it uses are on every Gorgias Helpdesk plan. See Pricing & Plans.
To set it up, follow Connect Gorgias and manage subscriptions from tickets. It takes about thirty minutes the first time: you copy and paste a few URLs, and there’s no code. This page is the reference: how it works, what each button does, what’s sent, and what to check when something looks wrong.
How it works
There’s no Connect button for Gorgias in Curobi, and nothing to install in Gorgias. The card is built from two features Gorgias already has, pointed at Curobi’s API with an API key you create:
- Gorgias’s HTTP integration calls Curobi whenever a ticket is created or updated, sending the ticket’s email address, and keeps the answer: that customer’s subscriptions.
- A custom HTTP widget shows the answer in the ticket sidebar. Each of its five buttons asks Curobi to make one change to one subscription.
Gorgias calls Curobi; Curobi never calls Gorgias. That’s why setup is an API key rather than a login. Curobi holds no Gorgias credentials and stores nothing from Gorgias, so there’s no connection on Curobi’s side to expire, break or clean up. The flip side is that Curobi has nothing to watch: if the card stops working, Curobi can’t warn you, and Gorgias’s Events tab is where the reason shows (see Checking it’s working).
A one-click connection is being considered, with no date set; until then, the step-by-step recipe is how you connect.
What agents see
The card lists the subscriptions of the customer whose email address is on the ticket, one collapsed block per subscription. Opening a block shows the fields kept in the recipe:
| On the card | What it shows |
|---|---|
| Status | The subscription’s state, for example ACTIVE or PAUSED |
| Products | The subscribed products |
| Bills | How often it bills, for example Every month |
| Next charge | The next charge date |
| Amount | The amount per charge |
| Currency | For example USD |
| Started with order | The order the subscription started from |
| Subscription # | The subscription’s number. The buttons use it, and it’s the number to quote when you contact Curobi support about one subscription |
- The customer is matched on the exact email address. Curobi looks the ticket’s address up in
Shopify and only accepts an exact match, so
ann@shop.comnever findsann@shop.com.au. A customer who writes in from a different address than the one on their Shopify account gets an empty card. - Cancelled subscriptions are listed too, so an agent can see what a customer used to have.
- Only Curobi subscriptions appear. Shopify lets an app see only the subscriptions that app created, so one made by another subscription app isn’t on the card. Subscribers you’ve moved over with CSV migration are Curobi subscriptions and do appear.
- Up to ten per customer. The lookup asks Curobi for ten subscriptions (
limit=10in its URL). - Every block has the same title. Gorgias titles each item in a list with the section’s name, so agents open a block to see its Products and Status.
What each button does
| Button | What happens |
|---|---|
| Skip next order | The next charge moves forward by one billing period, or to the next charge date on a fixed-calendar plan |
| Pause | Billing stops until the subscription is resumed |
| Resume | A paused subscription goes back to active |
| Reschedule | Asks the agent for a date and moves the next charge to it. Type it as 2026-12-01 or 2026-12-01T00:00:00Z. It must be in the future; on a fixed-calendar plan, Curobi moves it to the plan’s next charge date on or after the one typed |
| Cancel | Final. The customer stops being billed, and the subscription can’t be resumed from the card |
Each button changes the subscription straight away. It uses the same action as the matching button in the Curobi admin, so the card and the admin can’t disagree about what “pause” means.
After a click, Gorgias shows a confirmation and adds a line to the ticket, such as “Pause on CUROBI Subscriptions by …”, with a warning icon if the call failed. A few seconds later the card fetches the subscriptions again by itself, so the block’s Status changes without anyone refreshing. If it ever looks stale, add any tag to the ticket and refresh the page.
The ticket line is the record of who did what. Every button sends the same API key, so to Curobi every click looks alike. Gorgias is the one that knows which agent clicked.
A button that doesn’t fit the subscription’s state fails and changes nothing. Pausing a cancelled
subscription, resuming one that was never paused, or skipping when there’s no charge to skip fails
with a message starting state_conflict. Read the Status on the card and pick the action that fits.
A bad Reschedule date is refused before anything runs. A date in the past, or text that isn’t a
date, fails with invalid_request, and the agent can correct it and click again.
Why a double-click doesn’t skip twice
Every button’s URL carries an idempotency_key, a safety key built from the ticket number, the
subscription number and the button’s name. Curobi runs a request once per key. If an agent
double-clicks, or Gorgias sends the same request again, the change happens once and the repeat gets
the first click’s answer back.
That matters most for Skip next order. A skip that ran twice would push the charge out two periods, and nothing afterwards would show that it had happened twice.
The end of each key is what lets a deliberate second click through. Skip’s key ends with the next charge date; the keys for Pause, Resume and Reschedule end with the time the subscription last changed. Once a change lands, that value moves, the card refreshes, and the next click carries a new key. Until it moves, a repeat click counts as the same request. Cancel’s key has no such ending, because cancelling twice is the same as cancelling once.
Plans and development stores
The card is an API integration like any other: Gorgias calls Curobi’s Admin API with your key, so it needs what the API needs.
- Pro, on a paid Shopify plan. The plan is checked on every call. On any other plan, Gorgias’s
calls are refused with
plan_upgrade_required. - Not on development stores. The API stays off until a store is on a paid Shopify plan and Curobi Pro, so you can’t build the card on a development store before launch, the way you can with Klaviyo. See Development stores.
What Curobi sends, and what it doesn’t
- Gorgias sends Curobi the ticket’s email address, each time a ticket is created or updated. Curobi uses it to find the customer in Shopify and doesn’t store it.
- Curobi answers with each subscription’s status, products, billing frequency, dates, amounts and order number, plus Shopify ids.
- Never sent: names, email addresses, postal addresses or payment details.
- Why the key needs the Customer data permission anyway. Asking which subscriptions belong to an email address is a question about a person. So Curobi asks for the permission that decides who may ask about customers, even though the card shows no names or email addresses. A key without it can’t look anyone up.
- Your API key stays in a header. The key travels in the
Authorizationheader. The safety key in each button’s URL carries a ticket number, a subscription number and a date, none of which is a secret.
Checking it’s working
- In Gorgias: open Settings → App Store → HTTP Integration → CUROBI Subscriptions
→ Events. Each lookup is a
GETrow toapp.curobi.com; 200 OK means Curobi answered. Two rows for one new ticket is normal: Gorgias calls once for Ticket created and once more for its own update of the ticket. Click a row to see the request and Curobi’s response. - In Curobi: the API keys page shows when the
Gorgiaskey was last used.
Rate limits
Gorgias calls Curobi on every ticket update, adding a tag included, which is more often than it
sounds. Curobi’s API allows 60 requests a minute per store, with short bursts of up to 120. Past
that, Gorgias’s calls get 429 rate_limited and the card stays blank until the minute is up.
The limit is per store, not per key. Any other system calling your Curobi API, such as a
warehouse sync on its own key, draws from the same budget as Gorgias. If you see 429s regularly,
contact Curobi support.
Disconnecting
- In Gorgias, delete the CUROBI Subscriptions HTTP integration and the card.
- In Curobi, open Data & API → API keys and revoke the
Gorgiaskey.
Revoking the key alone is enough to stop everything. Every lookup and every button carries it, and a revoked key is refused on the very next request, with no grace period.
Uninstalling Curobi revokes every API key, so the card stops working straight away.
Moving below Pro switches the API off within a minute, so lookups and buttons are refused with
plan_upgrade_required.
Troubleshooting
Most problems show up in Gorgias’s Events tab (lookups) or in a button’s Request panel (buttons), with an error code from Curobi. The error reference explains every code.
| What you see | What it means | What to do |
|---|---|---|
| Empty card for a customer who has a subscription | The ticket’s email differs from their Shopify account email, or another app created the subscription | Check the email on the customer’s Shopify record |
403 plan_upgrade_required in the Events tab | The store isn’t on Pro, or is a development store | Upgrade from Plan & billing in Curobi, on a store with a paid Shopify plan |
403 insufficient_scope in the Events tab | The key is missing one of the three permissions | Create a key with all three (step 1) |
401 with missing_credential | The header’s key and value are swapped, so Gorgias sends a header named Bearer instead of Authorization. The Events tab’s Request panel shows it as Bearer: REDACTED | In the header row, the Key field must say Authorization and the Value field Bearer, a space, then the key |
401 with any other code | The Authorization value is wrong | Paste it again: Bearer, a space, the whole key |
A button shows Error 401 and its Request panel lists only Content-Type under Headers | The button has no Authorization header. Each button carries its own headers; the integration’s header doesn’t apply to it | Edit the button and add the header row (step 5) |
A button shows Error 403 with insufficient_scope | The key was created without write:subscriptions. Permissions are fixed when a key is made | Create a new key with all three permissions, revoke the old one, and paste the new key into the integration and every button |
400 invalid_request on Reschedule | The date is in the past, or isn’t a date | Type a future date as YYYY-MM-DD |
409 state_conflict on a button | The subscription isn’t in a state where that action makes sense | Read the Status on the card |
409 idempotency_conflict | The same safety key was used for a different request | Add a tag to the ticket to refresh the card, then try again |
429 rate_limited | More than 60 requests a minute from your store (short bursts of up to 120 are fine) | Wait a minute. If it keeps happening, contact Curobi support |
| The card never appears | Gorgias couldn’t reach Curobi within 5 seconds, or switched the integration off after repeated failures | Check the Events tab, and switch the integration back on |