How to Use the Gorgias API (2026): Auth, Endpoints & Examples
If you run support for an ecommerce brand on Gorgias and you want to pull tickets into a warehouse, sync customers from your store, auto-create a ticket when an order fails, or wire Gorgias into your own tooling, you'll be working with the Gorgias API. It's a clean REST API — but the first session is usually spent on the same handful of questions: what's the base URL, where do I get an API key, how does authentication actually work, and why am I getting a `429`?
This guide answers all of that in order. We'll cover what the Gorgias REST API is, where to find your API key, how Gorgias's Basic Auth works (with a real curl you can paste), the resources you'll reach for most (tickets, messages, customers, integrations, events), cursor pagination, rate limits, webhooks, and copy-paste examples in Python and Node. Details are verified against Gorgias's developer docs as of June 2026 — Gorgias revises the product periodically, so treat exact limits as "confirm in your account." New to the product itself? Start with what is Gorgias; if you'd rather connect existing tools than write code, the best Gorgias integrations is the companion piece.
What the Gorgias REST API is
Gorgias is a help desk built for ecommerce, and its API is a RESTful, JSON-over-HTTPS API. You make standard HTTP requests — GET to read, POST to create, PUT/PATCH to update, DELETE to remove — against resource URLs, and you get JSON back. There's no required SDK; anything that can make an HTTPS request can talk to it. Gorgias exposes resources for most objects in the product, so you can get, create, update, and delete customers, tickets, messages, and events programmatically.
Every request goes to your account's own subdomain. The base URL format is:
https://{your-subdomain}.gorgias.com/api/
So if your help desk lives at acme.gorgias.com, your tickets endpoint is https://acme.gorgias.com/api/tickets. There's no separate API host, and — unlike some help desks — the resource paths Gorgias documents don't carry a version segment (you'll see /api/tickets, not /api/v2/tickets). Your exact base URL is shown in the credentials screen described below, so copy it from there rather than hand-assembling it.
How to get your Gorgias API key
Gorgias supports two authentication modes, and which one you want depends on what you're building:
- Private app — API key (Basic Auth). For server-to-server scripts, internal integrations, and anything that only talks to your own account. This is what most readers of this guide want.
- Public app — OAuth2 (mandatory). Required if you're building a public integration that other Gorgias accounts will install. OAuth2 is out of scope here; if that's you, head to the developer portal.
To find your API key and credentials (per Gorgias's docs):
- From your help desk, click the Settings icon in the bottom-left corner.
- Open Account, then select REST API.
- Under API Access & Credentials you'll see three things: the Base API URL, your Username (your account email), and the Password (your API key).
If no key exists yet, create one from that screen. A few things worth knowing before you build:
- It's a secret. The key grants API access at your user's permission level. Treat it like a password — keep it out of client-side code, repos, and logs, and store it in an environment variable or a secrets manager.
- Rotation. You can reset the API key at any time from the same screen. Resetting generates a new key and immediately invalidates the old one, so plan to update your integrations when you rotate.
- Service accounts. For an integration that should outlive any one person, create a dedicated Gorgias user for it and use that user's email + key, so the integration doesn't break when someone leaves.
Gorgias API authentication: Basic Auth
For private apps, Gorgias uses HTTP Basic Authentication. The pairing is straightforward — and it's the part people get wrong most often:
- Username = your account email address
- Password = your API key
Under the hood, Basic Auth Base64-encodes username:password (here, your-email:your-api-key) and sends it as an Authorization: Basic ... header. In curl, the -u flag does this for you:
curl -s -u '[email protected]:YOUR_API_KEY' \
-H "Content-Type: application/json" \
-X GET 'https://acme.gorgias.com/api/tickets'
If your HTTP client has no Basic Auth helper, build the header yourself — Base64-encode [email protected]:YOUR_API_KEY and send:
Authorization: Basic <base64 of "[email protected]:YOUR_API_KEY">
That's the whole authentication story for the private-app path: the email + key pair is the credential, no token exchange required. (Public apps use OAuth2 instead — same API surface, different credential flow.)
The resources you'll actually use
Gorgias exposes a resource for nearly every object in the product. The ones you'll reach for most:
- Tickets —
/api/tickets. Create, read, update, and list tickets. The center of gravity for almost every integration. - Messages —
/api/tickets/{id}/messages. A message is a reply on a ticket. Messages can be public (incoming or outgoing, customer-visible) or internal notes (always outgoing, team-only). - Customers —
/api/customers. The shoppers/requesters behind your tickets. Create and sync them from your store or CRM. - Integrations —
/api/integrations. Programmatic management of the HTTP integrations Gorgias uses for things like webhooks. - Events —
/api/events. An activity stream of what happened in the account — useful for syncing and auditing.
A quick map of HTTP verbs to common actions:
| Action | Method | Example endpoint |
|---|---|---|
| List tickets | GET | /api/tickets |
| Get one ticket | GET | /api/tickets/{id} |
| Create a ticket | POST | /api/tickets |
| Update a ticket | PUT | /api/tickets/{id} |
| Add a message to a ticket | POST | /api/tickets/{id}/messages |
| List customers | GET | /api/customers |
| Create a customer | POST | /api/customers |
| List events | GET | /api/events |
The one rule that trips everyone up
In Gorgias, a ticket cannot exist without a message. That means the messages array is required when you create a ticket — you can't POST an empty ticket and add a reply later. The exact required fields inside that message depend on the channel you choose (api, email, chat, phone, or sms); for the api channel you supply the sender, the body, and a couple of routing flags. The next section shows a complete payload.
Example: create a ticket with curl
To create a ticket on the api channel, send a customer (with at least an email) plus a messages array containing the first message. Note the from_agent: false flags (this is an incoming message from the customer) and the channel/via set to "api":
curl -s -u '[email protected]:YOUR_API_KEY' \
-H "Content-Type: application/json" \
-X POST 'https://acme.gorgias.com/api/tickets' \
-d '{
"customer": { "email": "[email protected]" },
"channel": "api",
"via": "api",
"from_agent": false,
"status": "open",
"messages": [
{
"sender": { "email": "[email protected]" },
"subject": "Payment failed at checkout",
"body_text": "Customer reports a 502 when paying with card.",
"body_html": "Customer reports a 502 when paying with card.",
"channel": "api",
"via": "api",
"from_agent": false
}
]
}'
A successful create returns the full ticket object as JSON, including the new id you'll use for follow-up calls. To post a reply afterward, POST to /api/tickets/{id}/messages with from_agent: true for an outgoing agent reply.
Example: list and read tickets (Python)
Here's a minimal, dependency-light Python script using requests. It reads credentials from environment variables (never hard-code them) and fetches a page of tickets:
import os
import requests
SUBDOMAIN = "acme" # the part before .gorgias.com
EMAIL = os.environ["GORGIAS_EMAIL"]
API_KEY = os.environ["GORGIAS_API_KEY"]
BASE = f"https://{SUBDOMAIN}.gorgias.com/api"
# Basic Auth: account email as username, API key as password
auth = (EMAIL, API_KEY)
resp = requests.get(f"{BASE}/tickets", auth=auth, params={"limit": 100})
resp.raise_for_status()
payload = resp.json()
tickets = payload["data"]
print(f"Fetched {len(tickets)} tickets")
for t in tickets:
print(t["id"], t.get("subject"), "status:", t.get("status"))
List responses are wrapped — the records live under data, and pagination metadata (including the cursor for the next page) comes alongside it. See the pagination section below for how to walk every page.
Example: create a ticket (Node)
The same idea in Node using the built-in fetch (Node 18+). Basic Auth is just a Base64-encoded Authorization header:
const SUBDOMAIN = "acme";
const EMAIL = process.env.GORGIAS_EMAIL;
const API_KEY = process.env.GORGIAS_API_KEY;
const BASE = `https://${SUBDOMAIN}.gorgias.com/api`;
const authHeader =
"Basic " + Buffer.from(`${EMAIL}:${API_KEY}`).toString("base64");
const res = await fetch(`${BASE}/tickets`, {
method: "POST",
headers: {
Authorization: authHeader,
"Content-Type": "application/json",
},
body: JSON.stringify({
customer: { email: "[email protected]" },
channel: "api",
via: "api",
from_agent: false,
status: "open",
messages: [
{
sender: { email: "[email protected]" },
subject: "API test ticket",
body_text: "Created from Node.",
body_html: "Created from Node.",
channel: "api",
via: "api",
from_agent: false,
},
],
}),
});
if (!res.ok) {
throw new Error(`Gorgias error ${res.status}: ${await res.text()}`);
}
const ticket = await res.json();
console.log("Created ticket", ticket.id);
Pagination
Gorgias uses cursor-based pagination on its list endpoints. Two things to internalize:
- The
limitparameter defaults to 30 and maxes out at 100. Bumping it to 100 cuts the number of requests for the same data by more than three times — the single cheapest optimization you can make, and it keeps you well under the rate limit. - To walk through results, you follow the
next_cursorvalue returned with each page and pass it back as thecursorparameter on the next request. Keep going untilnext_cursorcomes backnull— that's the last page. You can also sort withorder_by.
# first page
curl -s -u '[email protected]:YOUR_API_KEY' \
'https://acme.gorgias.com/api/tickets?limit=100&order_by=created_datetime:desc'
# next page — pass the next_cursor value from the previous response
curl -s -u '[email protected]:YOUR_API_KEY' \
'https://acme.gorgias.com/api/tickets?limit=100&cursor=THE_NEXT_CURSOR'
One caveat worth designing around: cursors are opaque and short-lived — they can expire. Don't persist a cursor and reuse it hours later; treat it as a one-shot pointer for an in-progress sync, and restart the walk if it goes stale.
Rate limits
Gorgias rate-limits the API with a leaky bucket algorithm — your request budget refills steadily over time rather than resetting in one big block. The ceiling depends on your auth method, and limits apply per account (so all your keys share the same budget):
| Auth method | Approx. limit |
|---|---|
| API key (Basic Auth) | ~40 requests / 20-second window |
| OAuth2 (public app) | ~80 requests / 20-second window |
Some accounts — Enterprise in particular — are reported to use a tighter window (e.g. a 10-second bucket), and Gorgias has adjusted these figures over time, so confirm against the official limits page and your own response headers rather than hard-coding a number.
Don't guess your remaining budget — read it from the response headers. The two that matter most:
X-Gorgias-Account-Api-Call-Limit— your live usage against the account's budget.Retry-After— when you've been throttled, how many seconds to wait before retrying.
(Some clients also report standard X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset headers; treat those as a bonus and rely on the Gorgias-specific header above.)
When you exceed the limit, Gorgias returns HTTP 429. The correct pattern is to back off for the number of seconds in Retry-After, then retry — ideally with exponential backoff and jitter, and a request queue so you're spacing calls across the window rather than firing them all at once. Build this in from day one; it's the single most common thing that breaks naive integrations at scale.
Webhooks
If you want Gorgias to push to you instead of polling, use webhooks via HTTP integrations. A webhook is an automatic message Gorgias sends to a URL you control whenever a specific event happens, so your other tools can react in real time. You configure them in Settings → Integrations → HTTP (and can also manage them through the /api/integrations resource).
Common events you can subscribe to include:
ticket-createdticket-updatedticket-message-createdcustomer-createdcustomer-updated
The usual pattern: stand up an HTTPS endpoint, subscribe it to the events you care about, verify and acknowledge each delivery quickly (return a 2xx), and do the heavy work asynchronously so a slow handler doesn't cause retries. Webhooks are almost always cheaper than polling the API on a timer — and they keep you comfortably inside the rate limit.
When you'd reach for an AI layer instead of the raw API
The API is the right tool when you want deterministic, programmatic control — syncing data, wiring Gorgias into your own stack, or creating tickets from other systems. But a growing share of "API projects" are really "I want tickets to be triaged and answered automatically," and that's a different shape of problem. Writing and maintaining those scripts — classify the ticket, look up the order, draft a reply, decide whether it's safe to send — is a real engineering commitment, and it gets brittle as your catalog and policies change.
That's the gap an AI agent layer fills. One honest caveat for Gorgias readers specifically: Macha, the AI agent layer we work on, runs on top of Zendesk and Freshdesk only — it does not integrate with Gorgias today, so it isn't an option for your stack right now. We mention it just so the comparison is concrete: rather than scripting triage-and-reply logic against the raw API, an agent layer triages, drafts, and resolves routine tickets using your connected knowledge base, and escalates anything it can't confidently handle to a human with full context. (We built this on Zendesk first — see Macha on Zendesk for how the model works.) If you're on Gorgias and want that outcome, you'll be looking at Gorgias's own Automate/AI Agent features or a Gorgias-compatible tool — see the best Gorgias integrations. If and when you're on Zendesk or Freshdesk, you can try Macha free — 7-day free trial, no credit card required.
Frequently asked questions
What is the Gorgias API base URL? It's your own subdomain plus /api/: https://{your-subdomain}.gorgias.com/api/. For example, an account at acme.gorgias.com reaches tickets at https://acme.gorgias.com/api/tickets. The resource paths Gorgias documents don't include a version segment, and your exact Base API URL is shown on the REST API credentials screen.
Where do I find my Gorgias API key? Click the Settings icon in the bottom-left of your help desk, open Account → REST API, and look under API Access & Credentials for the Base API URL, your Username (account email), and Password (the API key). Create one there if it doesn't exist; you can reset it any time, which immediately invalidates the old key.
How does Gorgias API authentication work? For private apps, with HTTP Basic Auth: your account email is the username and your API key is the password. The pair is Base64-encoded into an Authorization: Basic ... header (in curl, -u '[email protected]:YOUR_API_KEY'). Public apps must use OAuth2 instead.
What are the Gorgias API rate limits? Roughly 40 requests per 20-second window for API-key (Basic Auth) integrations and 80 for OAuth2, applied per account via a leaky-bucket algorithm; some plans use a tighter window. Read X-Gorgias-Account-Api-Call-Limit from responses, and when you get a 429, wait the number of seconds in Retry-After before retrying. Confirm exact figures in Gorgias's docs and your own account.
How do I paginate Gorgias API results? With cursors. List endpoints return 30 records by default; set limit up to 100, then follow the next_cursor value (passed back as the cursor parameter) until it returns null. Cursors are opaque and short-lived, so don't store them for later.
Can I create a ticket without a message? No. In Gorgias a ticket can't exist without a message, so the messages array is required when you POST /api/tickets. The required message fields depend on the channel (api, email, chat, phone, sms).
The bottom line
The Gorgias REST API is straightforward once the basics click: every call goes to https://{your-subdomain}.gorgias.com/api/, you authenticate with Basic Auth using your account email as the username and your API key as the password, and you work with JSON resources for tickets, messages, customers, integrations, and events. The two things that catch everyone are the "a ticket needs a message" rule (the messages array is mandatory) and the rate limits — so structure your create payloads correctly and build 429/Retry-After handling in from the start. With those in place, paginate via the next_cursor, prefer webhooks over polling, and you can sync, create, and update almost anything in your help desk. From here, see what Gorgias is for the product overview, or the best Gorgias integrations if your real goal is connecting tools rather than writing code.
Gorgias REST API details verified against Gorgias's developer and support documentation, June 2026. Gorgias updates its API, limits, and field requirements periodically — confirm endpoints, rate limits, and payload shapes in the live docs and your own account before relying on them.
Add AI agents to your Gorgias
Macha resolves tickets end to end on Gorgias — no migration, no code.
Zendesk
Freshdesk
Gorgias
Front
Shopify
Stripe
Slack
Notion
Google Workspace
Confluence

