Skip to content

02 Get your data in /Integrations

Gorgias

Send Gorgias tickets and their messages to Dimension Labs with the universal API.

  1. G GorgiasTickets, chats, calls, reviews
  2. ⟳ Your jobPull new · map fields · every 15 min
  3. { } Universal APIPOST /track · /trackhistorical
  4. 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.

  • 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. In your helpdesk, click the Settings icon in the bottom left corner.
  2. Under Account, select REST API.
  3. Under API Access & Credentials, copy the Base API URL (https://{your-domain}.gorgias.com/api/) and your Username.
  4. Under Password (API Key), click Create API Key if you don’t have one, then copy it.
  5. 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.

List tickets ordered by when they last changed, newest first, and stop once you reach tickets older than your cursor:

Terminal window
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).

Dimension LabsGorgiasNotes
textmessage stripped_text, else body_textstripped_text drops signatures and quoted replies. Skip messages where public is false: those are internal notes.
userIdticket customer.idGorgias’s internal customer id, on both their messages and your replies. Fall back to the sessionId.
incomingmessage from_agentfrom_agent is true when your company sent the message, so incoming is its opposite.
sessionIdticket idPrefix it, for example gorgias-123.
conversationIdticket idSame value as sessionId.
dimensionlabs_timestampmessage created_datetimeConvert with toMillis. Gorgias’s example values have no time zone offset; toMillis reads those as UTC.
platformJsonticket channel, status, tags, language; message channel, viaTo 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.

// 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;
}

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-01 sends 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.

Checked against Gorgias’s documentation on 2026-10-13.