# Zapier

> Send records from any of Zapier's apps to Dimension Labs with a Zap and the universal API, without running your own server.

Zapier connects to thousands of apps ([Zapier's app directory](https://zapier.com/apps) lists 9,000+ as of 2026-10-26). If a tool you use has a Zapier trigger, such as a new form response, review, ticket or spreadsheet row, a Zap can send each new record to the [universal API](/api/tracker). There's no server to run: Zapier runs the Zap each time the trigger fires.

Zapier fits sources where one trigger event is one piece of customer text: a form or survey response, a review, a feedback submission, the first message of a ticket. For full multi-message conversations, or to load history, use the app's own guide or [Any other system](/integrations/other-sources), which pull every message in order.

## What you need

- A Zapier account. Code steps and their limits depend on your Zapier plan ([Use JavaScript code in Zaps](https://help.zapier.com/hc/en-us/articles/8496310939021)).
- A Zapier trigger for your app that returns the customer's text and a date.
- A Dimension Labs API key for a new **Universal API** source. See [Your API key](/api/tracker#your-api-key).

## 1. Choose the trigger

1. In the Zap editor, add the trigger for your app, for example a new response, new review or new row.
2. Test it and check the sample record has three things: the customer's text, an id for the record, and when it was written.

Use one source in Dimension Labs per app, so its data is easy to filter later.

## 2. Add a Code by Zapier step

Zapier's own steps are in [Use JavaScript code in Zaps](https://help.zapier.com/hc/en-us/articles/8496310939021).

1. Click the **+** icon to add a step, then search for and select **Code by Zapier**.
2. In the **Code** dropdown, choose **JavaScript**.
3. Under **Input Data**, add these keys and map each to a field from your trigger:

| Key | Map it to | Notes |
|---|---|---|
| `text` | the customer's words | A review, an answer, a message. |
| `recordId` | the record's own id | Response id, review id, ticket id. Becomes `sessionId`. |
| `customerId` | your internal customer id, if the trigger has one | Optional. Never an email address or name. |
| `writtenAt` | when the record was written | A date with a time zone works best, such as `2026-10-26T14:03:00Z`. |
| `apiKey` | your Dimension Labs API key | Paste it as text. |
| `source` | the app's name, typed as text | For example `jotform`. Kept in `platformJson`. |

Add any other fields you want to filter or join on later (a rating, a location id, a form name) as extra keys; the code puts every extra key into `platformJson`.

The code uses Zapier's built-in `fetch`, and sends a message more than an hour old to `/trackhistorical`, as every guide does.

## 3. Send it

Paste this into the **Code** box:

```js
// Code by Zapier (JavaScript). Sends one record to the Dimension Labs universal API.
const { text, recordId, customerId, writtenAt, apiKey, ...extra } = inputData;
const clean = (s) => String(s).replace(/:/g, '-');   // ids can't contain colons

if (!text || !text.trim()) {
  output = { skipped: 'no text' };
} else {
  const ts = Date.parse(writtenAt);
  if (Number.isNaN(ts)) throw new Error(`Can't read the date "${writtenAt}". Map a date with a time zone.`);
  const sessionId = clean(`${extra.source || 'zapier'}-${recordId}`);
  const message = {
    text,
    userId: customerId ? clean(customerId) : sessionId,
    incoming: true,
    sessionId,
    conversationId: sessionId,
    dimensionlabs_timestamp: ts,
    platformJson: extra,
  };
  const endpoint = Date.now() - ts > 60 * 60 * 1000 ? 'trackhistorical' : 'track';
  const url = `https://tracker.dimensionlabs.io/${endpoint}?platform=universal&v=11.1.0-rest&type=incoming&apiKey=${encodeURIComponent(apiKey)}`;
  const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(message) });
  if (!res.ok) throw new Error(`Dimension Labs returned ${res.status}: ${await res.text()}`);
  output = { sent: sessionId, endpoint };
}
```

`JSON.stringify` escapes quotes and line breaks in the customer's text, which is why this guide uses a code step rather than typing the JSON by hand: a review with a quotation mark in it would break hand-typed JSON.

Click **Run Code** to test it. A result with `sent` means the message reached Dimension Labs.

## 4. Turn it on

- **Publish** the Zap. Each new record is sent as it arrives, to `/track`, and is enriched automatically every day.
- **If Zapier sees a record late** (more than an hour after it was written), the code sends it to `/trackhistorical`. Run a [backfill](/dimensions/backfill) from the **Backfill** tab to enrich those.
- **History:** Zaps only see new records. Export your history from the app and [upload a file](/data/upload-a-file) (check it with the [file checker](/data/check-a-file)), then run a backfill.
- **Re-runs are safe:** if Zapier replays a run, duplicates are removed automatically.

**Personal data.** Don't map email addresses, names or phone numbers into any key: every extra key is sent as `platformJson`. Redact the text if customers include personal details. See [PII redaction](/data/pii-redaction).

## A record with several messages

If the trigger returns a whole conversation (a ticket with replies, a chat transcript), each message needs its own `POST`, in order, at least one second apart, with replies from your side marked `incoming: false` and `type=outgoing`. That is easier and more reliable in a script: see the app's guide, or [Any other system](/integrations/other-sources).

## Zapier reference

- [Zapier app directory](https://zapier.com/apps)
- [Use JavaScript code in Zaps](https://help.zapier.com/hc/en-us/articles/8496310939021)
- [JavaScript code examples in Zaps](https://help.zapier.com/hc/en-us/articles/8496197098253)
- [Send webhooks in Zaps](https://help.zapier.com/hc/en-us/articles/8496326446989-Send-webhooks-in-Zaps)

Checked against Zapier's documentation on 2026-10-26.
