Skip to content
Cover illustration for ChatGPT Ads offline conversions: how to send CRM, phone and in-store sales to OpenAI

ChatGPT Ads offline conversions: how to send CRM, phone and in-store sales to OpenAI

How to get offline outcomes into ChatGPT Ads: what OpenAI’s Conversions API accepts for CRM, phone and in-store events, which stages to send, the 7-day and 30-day clocks, LiveRamp’s invite-only program, and what isn’t documented yet.

Jamie IsabelBy 10 min read

ChatGPT Ads takes offline conversions through OpenAI’s Conversions API. Your server sends each CRM, phone or in-store outcome with an offline action source, the click reference you saved on the lead, and hashed contact details, within 7 days of the sale.

This guide is part of our offline conversions series. It assumes you already have a data source, a Pixel ID and a Conversions API key. If not, start with the ChatGPT Ads Conversions API guide, which covers the Pixel, the server setup and deduplication.

What OpenAI supports for offline conversions

ChatGPT Ads is a new platform, and OpenAI documents little that is specific to offline conversions. As of October 2026, this is what its docs confirm:

  • Offline action sources. The Conversions API reference accepts action_source values of web, mobile_app, offline, physical_store, phone_call, email and other. Only web events need a source_url.
  • Send everything you may share. OpenAI recommends sending all conversion events, not just those with an oppref. Its measurement guide says hashed contact information can help when click information is incomplete.
  • Partners. OpenAI’s partner guide points to LiveRamp for offline conversions such as in-store purchases. It also lists Hightouch, which syncs event models to an OpenAI destination with your Pixel ID and API key, and Datahash, which helps implement the Conversions API.

What the docs don’t describe: a file or CSV upload for conversions in Ads Manager, a definition of each action source, or a way to correct a conversion after it’s sent. We cover those gaps further down.

Direct Conversions API upload vs LiveRamp’s program

There are two documented routes for offline outcomes. LiveRamp’s OpenAI Conversions API program passes a file through the same API. Click through to compare them.

Access

Direct Conversions API

Your own server, with a Pixel ID and a Conversions API key from Ads Manager

LiveRamp program

Limited availability, by invitation only. Ask your LiveRamp or OpenAI rep.

1 / 6

From OpenAI’s Conversions API and event quality documentation and LiveRamp’s program pages, October 2026.

LiveRamp’s setup starts with a sample file, then a destination account in LiveRamp Connect with your Pixel ID and Conversions API key. LiveRamp says the key is generated once, so store it when you create it. Each row needs at least one identifier (name and postal address, email or phone) plus the event name, transaction category, timestamp, amount and order ID.

What you need before you start

  1. A data source in the Conversions section of Ads Manager, its Pixel ID, and a Conversions API key for the same ad account. A server-only setup still needs a Pixel ID.
  2. The oppref click reference saved on each new lead, plus the email and phone the person gave you, and their consent choice.
  3. A CRM that keeps those fields on the contact and links each deal or order back to it.
  4. A short list of CRM stages to send, each mapped to an OpenAI event name.
  5. A conversion event setting in Ads Manager for each stage you want to report, attached to your campaigns.
  6. A server process that can send an event when a stage changes, not only in a weekly batch.

How to send CRM conversions to ChatGPT Ads

1. Save the click reference on the lead

OpenAI appends oppref to the landing page URL. The Pixel stores it in a first-party __oppref cookie for 30 days. Read that value when the form is submitted and save it on the lead, next to the email, phone and a timestamp. OpenAI says to pass it unchanged and never to invent one or reuse another visitor’s.

Our default is to capture click references from your own tracking domain: a server container on a subdomain such as sgtm.example.com. Google’s custom domain guide says a container on the provider’s default domain can only set JavaScript cookies, while your own subdomain gets full access to server-set cookies. The server-side tagging guide covers the setup.

An ad click is carried through a form, a sales call and a CRM outcome before it returns to an advertising report.

2. Pick the CRM stages to send

Send the stages that tell OpenAI which leads turned into revenue. Use a standard event where one fits, from OpenAI’s supported events, and a custom event where none does.

CRM stageEvent typeaction_sourceNotes
Form submitted on the sitelead_createdwebUsually sent by the Pixel at submit. If your server sends it too, reuse the same event ID.
Meeting booked by a repappointment_scheduledphone_call or offlineOpenAI’s event for a booked meeting, demo or consultation.
Qualified leadcustom, with a name such as qualified_leadofflineCustom names are 1–64 characters and can’t reuse a standard name. Not usable as an optimization goal.
Deal won on a callorder_created, with amount and currencyphone_callOpenAI’s event for a completed purchase.
In-store purchaseorder_createdphysical_storeSend the order total as the event amount.
Paid subscription startssubscription_createdofflineUses the plan_enrollment data shape, with an optional plan_id.
Event names and action source values are OpenAI’s. OpenAI doesn’t define when to use each action source; the pairings are how we map them.

Give every stage its own event ID, such as deal_10427_won. Keep that ID if you retry, and use a new one for each different action.

3. Build and send the event

Offline events go to the same endpoint as web events. Leave out source_url, add the saved oppref, and add the hashed identifiers you have. This batch sends a qualified lead and a won deal:

Server: two CRM stages in one Conversions API request
POST https://bzr.openai.com/v1/events?pid=<PIXEL-ID>
Authorization: Bearer <CONVERSIONS-API-KEY>
Content-Type: application/json

{
  "events": [
    {
      "id": "lead_8f2k91_qualified",
      "type": "custom",
      "custom_event_name": "qualified_lead",
      "timestamp_ms": 1792990000000,
      "action_source": "offline",
      "oppref": "<oppref saved on the lead>",
      "user": {
        "emails_sha256": ["<SHA-256 of the normalized email>"],
        "external_ids_sha256": ["<SHA-256 of your CRM contact ID>"]
      },
      "data": { "type": "custom" }
    },
    {
      "id": "deal_10427_won",
      "type": "order_created",
      "timestamp_ms": 1793000000000,
      "action_source": "phone_call",
      "oppref": "<oppref saved on the lead>",
      "user": {
        "emails_sha256": ["<SHA-256 of the normalized email>"],
        "phone_numbers_sha256": ["<SHA-256 of 14155552671>"]
      },
      "data": { "type": "contents", "amount": 1200000, "currency": "USD" }
    }
  ]
}
  • Time. timestamp_ms is when the stage changed in your CRM, in Unix milliseconds, not when you send it.
  • Value. Amounts are integers in minor units, so 1200000 is $12,000.00. A currency is required with an amount.
  • Hashing. Trim and lowercase emails. For phones, keep the country code, remove whitespace, parentheses, periods and hyphens, then a leading + and any leading zeros. Then SHA-256 each value as lowercase hex. Each list takes at most 3 values.
  • IP and user agent. OpenAI asks for the real client’s values and says not to substitute your server’s. A CRM stage has no browser behind it, so leave them out.
  • Batches. Up to 1,000 events per request. One invalid event fails the whole batch.

In our own integration, CRM stage events use offline as the action source unless the stage happened on a call or in a store.

4. Attach the events to your campaigns

Sending an event doesn’t make it a conversion. OpenAI’s conversion tracking guide connects events to campaigns through a conversion event setting: one event type, one data source and an attribution window. For a custom event, the setting’s custom_event_name must match exactly. Updating a campaign’s list of settings through the API replaces the list, so include the ones you want to keep.

A conversion-optimized campaign takes exactly one standard event, chosen when you create it. Custom events, such as a qualified lead, can be reported on but not used as that goal.

The two clocks: 7 days to send, 30 days to credit

Two separate time limits decide whether a CRM outcome counts. OpenAI’s troubleshooting guide says they are not the same thing.

  • The send limit. Each event’s timestamp must be within the last 7 days and no more than 10 minutes in the future. You can’t backfill older CRM history, and OpenAI says not to change an old event’s time to make it pass. Its event quality check also flags server events that arrive more than 1 hour after the action, so send stages as they change.
  • The attribution window. A conversion is credited only if it happens within the window after an eligible ad click. OpenAI’s API reference says to use 30 days for a conversion event setting. A deal that closes 45 days after the click falls outside it, so send an earlier stage, such as a qualified lead, as well.

Reporting has its own settings. OpenAI’s Measure Results guide lets you pick a 7, 14 or 30-day click window and a 0 or 1-day view window. These change reporting only, not optimization, bidding or billing. Per the reporting docs, results are dated by the ad interaction by default, so a deal won today shows up on the day of the click. Set the time basis to conversion time when you compare with CRM close dates.

On view-through: OpenAI’s developer docs describe a one-day view window for web events, and say app events stay click-through only. They don’t say how it applies to offline action sources. LiveRamp’s page says its program helps with view-through conversions. Its FAQ also links its 3-day cadence to a 21-day attribution window, which differs from the 30 days in OpenAI’s docs, so confirm which applies with your rep.

Field mapping: CRM to Conversions API

CRM fieldConversions API fieldNotes
Saved click referenceopprefThe original string, unchanged. An event-level field, not inside user.
Stage or deal IDidUnique per action. Reuse it on retries.
Stagetype, plus custom_event_name for customMust match the conversion event setting exactly.
Stage change timetimestamp_msUnix milliseconds, within the last 7 days.
Where it happenedaction_sourceoffline, phone_call, physical_store and others
Emailuser.emails_sha256Trimmed, lowercased, SHA-256. Up to 3 values.
Phoneuser.phone_numbers_sha256Country code and digits only, then SHA-256.
CRM contact IDuser.external_ids_sha256Trimmed, case kept, then SHA-256. Use a stable ID per person.
First and last nameuser.first_names_sha256, user.last_names_sha256Lowercase, no spaces or ASCII punctuation, then SHA-256.
Postal code, city, countryuser.postal_codes, user.cities, user.countriesRaw values, not hashed. Country is a two-letter code.
Deal valuedata.amount and data.currencyInteger minor units with an ISO 4217 code.
Field names and normalization rules from OpenAI’s Conversions API reference, October 2026.

How to check that it works

  1. Send one batch with validate_only set to true. It checks the format without saving the events, and those events don’t appear in monitoring.
  2. Send one real stage change, then call the recent events endpoint (GET /v1/conversions/events with your pid) with the Advertiser API key. It returns a sample from roughly the last 15 minutes. Server events show the server_to_server channel.
  3. Check that the event type and custom event name match the conversion event setting on the campaign.
  4. After 24 to 48 hours, compare Ads Manager with your CRM for the same dates, with the time basis set to conversion time and the same click and view windows.
  5. Open event quality for the data source a few days later. It refreshes daily over 7 complete days, and warns about missing matching data or delayed server events.

Common errors and fixes

SymptomLikely causeFix
Old deals are rejectedThe timestamp is more than 7 days old, or was sent in secondsSend stages as they change, in milliseconds. Older history can’t be sent.
A whole batch is rejectedOne invalid event fails the batchCheck the batch with validate_only, fix the bad event, and resend with the same IDs.
A web event is rejectedaction_source is web but there is no source_urlUse an offline action source for CRM stages, or add the page URL.
The API returns an authentication errorThe Advertiser API key was used instead of the Conversions API keyUse the Conversions API key for the same ad account as a Bearer token.
Events arrive but show zero conversionsNo matching conversion event setting on the campaign, or the stage fell outside the click windowAttach a setting with the exact event name, and send earlier stages.
Few offline events are creditedNo oppref on the lead, and little hashed contact dataSave oppref at form submit, and send email, phone and a hashed CRM ID.
Event quality flags delayed server eventsA daily or weekly batchSend each stage soon after it changes in the CRM.
HTTP 400 on customer dataA user list has more than 3 valuesSend at most 3 hashed values per list. The API does not truncate.
From OpenAI’s Conversions API reference, troubleshooting guide and event quality guide, October 2026.

What isn’t supported or isn’t documented

  • No file upload in Ads Manager. OpenAI’s conversion guides cover the Pixel, the Conversions API, an image tag and partner integrations. None describe a file or CSV upload for conversions.
  • No corrections. OpenAI says not to resend a duplicate to change an event’s value or matching data, and doesn’t document a way to adjust or retract a conversion. Send the right value the first time.
  • No backfill. The 7-day timestamp limit means CRM history older than a week can’t be sent.
  • No action source definitions. OpenAI lists the values but doesn’t say how each one is used in attribution or reporting.
  • No optimizing on custom stages. Conversion-optimized campaigns take one standard event, which can’t be changed after the campaign is created.
  • No CRM write-back from HubSpot. OpenAI’s HubSpot article covers connecting accounts, creating campaigns and viewing performance in HubSpot. It doesn’t describe sending deal stages back as conversions.

How ChatGPT Ads fits with your other platforms

The groundwork is the same everywhere: save the click ID and contact details when the lead arrives, keep them on the CRM record, and send each stage inside the platform’s limits. Our guide to offline conversions compares match keys and upload windows across platforms.

Maven sends CRM stages to OpenAI Ads through its Conversion Events API, with the saved click reference and hashed contact details, alongside Google Ads and Meta. To check the website side first, a Free Tracking Scan shows which tags load on your lead pages today.

Get the next one before it hits.

Short emails when Meta, Google, GA4 or LinkedIn change something that moves your numbers.

Frequently asked questions

Can I upload offline conversions to ChatGPT Ads?

Yes, through the Conversions API. Your server sends each CRM, phone or in-store outcome as an event with an action_source such as offline, phone_call or physical_store. OpenAI’s docs don’t describe a file upload for conversions in Ads Manager. LiveRamp runs a file-based OpenAI program for offline conversions, which it says is in limited availability and by invitation only.

Which action_source should I use for CRM conversions?

The Conversions API accepts web, mobile_app, offline, physical_store, phone_call, email and other. OpenAI lists the values but doesn’t define when to use each one. We use phone_call for sales closed on a call, physical_store for in-store sales, and offline for other CRM stages. Events with action_source web must also include source_url.

How long after a sale can I send it to ChatGPT Ads?

The event timestamp must be within the last 7 days and no more than 10 minutes in the future, so send each outcome within 7 days of when it happened. To be credited to an ad, it also has to fall inside the attribution window. OpenAI’s docs use a 30-day click window for conversion event settings.

Do offline conversions need the oppref click reference?

No, but it helps. oppref is the click reference OpenAI adds to the landing page URL. Save it on the lead and send it unchanged with the later event. OpenAI also recommends sending every conversion you are permitted to share, not just those with an oppref, and adding hashed email, phone or customer ID for matching.

What is LiveRamp’s OpenAI Conversions API program?

It is a LiveRamp service that takes a file of offline conversions with customer details and passes it to OpenAI’s Conversions API. LiveRamp says it is in limited availability and by invitation only. You upload by SFTP or from a cloud bucket, within 7 days of the conversion, using your Pixel ID and a Conversions API key.

Can a campaign optimize toward a qualified lead from my CRM?

Only if you send it as a standard event. A qualified lead usually has no standard event name, so it goes in as a custom event. Custom events can be measured on any campaign, but OpenAI says they cannot be the goal of a conversion-optimized campaign.

Does the HubSpot integration send deal stages to ChatGPT Ads?

OpenAI’s HubSpot article covers connecting the accounts, creating campaigns from HubSpot and viewing performance there. It does not describe sending HubSpot lifecycle or deal stages back to ChatGPT Ads as conversions. For that, send the stages through the Conversions API or a partner.

Why don’t my CRM numbers match Ads Manager?

Your CRM counts every sale. Ads Manager counts sales it credits to an ad, within the selected click and view windows. Reports also date conversions by the ad interaction by default, not by the close date. Set the time basis to conversion time and use the same windows when you compare.

Sources and references

Published October 26, 2026

Find what your tracking misses in about 10 seconds.

Run a Free Tracking Scan on your site and see every gap we find.