02 Get your data in /Integrations
Gorgias
Send Gorgias tickets and their messages to Dimension Labs with the universal API.
- G GorgiasTickets, chats, calls, reviews
- ⟳ Your jobPull new · map fields · every 15 min
- { } Universal APIPOST /track · /trackhistorical
- Dimension LabsRead in full · enriched daily
This brings in each Gorgias ticket as one conversation: the customer’s messages and your agents’ and rules’ replies, across email, chat, SMS and social channels. You run it on your side: a small script pulls from the Gorgias REST API and posts each message to the universal API.
What you need
Section titled “What you need”- A Gorgias account owner or admin: they can see the API credentials and create API keys.
- Your Gorgias username (the email address on your account) and API key.
- A Dimension Labs API key for a new Universal API source. See Your API key.
1. Get API access in Gorgias
Section titled “1. Get API access in Gorgias”- In your helpdesk, click the Settings icon in the bottom left corner.
- Under Account, select REST API.
- Under API Access & Credentials, copy the Base API URL (
https://{your-domain}.gorgias.com/api/) and your Username. - Under Password (API Key), click Create API Key if you don’t have one, then copy it.
- Authenticate with Basic auth: your username and the API key (access your REST API credentials, access tokens).
The key acts as the user who holds it, with that user’s permissions.
2. Pull new tickets
Section titled “2. Pull new tickets”List tickets ordered by when they last changed, newest first, and stop once you reach tickets older than your cursor:
curl -u "$GORGIAS_USERNAME:$GORGIAS_API_KEY" \ "https://YOUR_DOMAIN.gorgias.com/api/tickets?order_by=updated_datetime:desc&limit=100"limit goes up to 100. Pass meta.next_cursor from the response as cursor to get the next page (pagination).
For each ticket, list messages with GET /api/messages?ticket_id=ID&order_by=created_datetime:asc&limit=100. The older “list messages of a ticket” endpoint is deprecated.
From September 8, 2026, Gorgias archives the original body_text and body_html of email messages 30 days after they are sent or received, and sets those fields to null when a stripped version exists. Use stripped_text, which isn’t affected, and fall back to body_text (email message data retention).
Rate limits, per Gorgias: API key integrations can make 40 requests in a 20 second window (Enterprise accounts: a 10 second window). Going over returns 429 with a Retry-after header (rate limits).
3. Map the fields
Section titled “3. Map the fields”| Dimension Labs | Gorgias | Notes |
|---|---|---|
text | message stripped_text, else body_text | stripped_text drops signatures and quoted replies. Skip messages where public is false: those are internal notes. |
userId | ticket customer.id | Gorgias’s internal customer id, on both their messages and your replies. Fall back to the sessionId. |
incoming | message from_agent | from_agent is true when your company sent the message, so incoming is its opposite. |
sessionId | ticket id | Prefix it, for example gorgias-123. |
conversationId | ticket id | Same value as sessionId. |
dimensionlabs_timestamp | message created_datetime | Convert with toMillis. Gorgias’s example values have no time zone offset; toMillis reads those as UTC. |
platformJson | ticket channel, status, tags, language; message channel, via | To join to order or account data, use customer.external_id (your own customer id) if you set it. |
Personal data. Don’t send customer.email or the customer’s name. Messages can hold addresses, phone numbers and order details: redact them before you send. See PII redaction.
4. Send it
Section titled “4. Send it”// gorgias.mjs. Environment: GORGIAS_DOMAIN, GORGIAS_USERNAME, GORGIAS_API_KEY, DL_API_KEY.import { sendToDimensionLabs, toMillis } from './dimensionlabs.mjs';
const HOUR = 60 * 60 * 1000;const sleep = (ms) => new Promise((r) => setTimeout(r, ms));const base = `https://${process.env.GORGIAS_DOMAIN}.gorgias.com/api`;const auth = 'Basic ' + Buffer.from(`${process.env.GORGIAS_USERNAME}:${process.env.GORGIAS_API_KEY}`).toString('base64');
// Retries Gorgias's rate limits (429) and server errors (5xx), honoring Retry-After.async function get(url) { for (let attempt = 0; ; attempt++) { const res = await fetch(url, { headers: { Authorization: auth } }); if (res.ok) return res.json(); if ((res.status !== 429 && res.status < 500) || attempt === 5) throw new Error(`Gorgias returned ${res.status}: ${await res.text()}`); await sleep((Number(res.headers.get('retry-after')) || 2 ** attempt) * 1000); }}
// Reads every page, or stops after the first page where stop(item) is true.async function list(path, stop = () => false) { const items = []; for (let cursor = ''; cursor !== null; ) { const page = await get(`${base}${path}&limit=100${cursor ? `&cursor=${encodeURIComponent(cursor)}` : ''}`); items.push(...page.data); cursor = page.data.some(stop) ? null : page.meta?.next_cursor ?? null; } return items;}
// Sends every public message written at or after `since` (Unix ms). Returns the new `since`.export async function syncGorgias({ since, historical = false }) { let newest = since; const changed = (t) => toMillis(t.updated_datetime) >= since; const tickets = await list('/tickets?order_by=updated_datetime:desc', (t) => !changed(t)); for (const t of tickets.filter(changed)) { for (const m of await list(`/messages?ticket_id=${t.id}&order_by=created_datetime:asc`)) { const ts = toMillis(m.created_datetime); const text = m.stripped_text ?? m.body_text; if (!m.public || ts < since || !text?.trim()) continue; await sendToDimensionLabs({ text, userId: t.customer?.id ? String(t.customer.id) : `gorgias-${t.id}`, incoming: !m.from_agent, sessionId: `gorgias-${t.id}`, conversationId: `gorgias-${t.id}`, dimensionlabs_timestamp: ts, platformJson: { channel: m.channel, via: m.via, status: t.status, tags: t.tags, language: t.language, customer_external_id: t.customer?.external_id }, }, { historical: historical || ts < Date.now() - HOUR }); newest = Math.max(newest, ts); } } return newest;}5. Run it
Section titled “5. Run it”Save the code as gorgias.mjs in a project set up as in Set up your project, and run it with the scheduled sync runner: import { syncGorgias as sync } from './gorgias.mjs';.
- History first:
node run.mjs 2025-01-01sends every message since that date to/trackhistorical. Then start a backfill from the Backfill tab. - Then every 15 minutes: the scheduled job sends new messages to
/track, and they are enriched automatically every day. A message that is more than an hour old when the job sees it goes to/trackhistorical, and needs a backfill. - Re-runs are safe: duplicates are removed automatically.
Gorgias allows 40 requests in 20 seconds, and each ticket costs at least one call, so a history load takes a while; the code waits whenever Gorgias asks it to. You can also upload a file of exported tickets (check it with the file checker), then run a backfill.
Gorgias reference
Section titled “Gorgias reference”- Access your Gorgias REST API credentials
- Access tokens (API keys)
- Authentication
- List tickets
- The Ticket object
- List messages
- The TicketMessage object
- Pagination
- Rate limits
- New email message data retention policy
Checked against Gorgias’s documentation on 2026-10-13.