> For the complete documentation index, see [llms.txt](https://help.ringtonic.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.ringtonic.app/guides/google-ads-integration.md).

# Google Ads Integration

Push offline conversions from your Ring Tonic funnel back to Google Ads so Smart Bidding actually knows which clicks turn into customers. When a lead in Ring Tonic reaches a mapped stage (e.g. **Won**), Ring Tonic uploads a conversion to your chosen Google Ads conversion action — with hashed identifiers, the originating click ID, and the deal value.

<figure><img src="/files/akJhlp0wF4Oh676kOiVg" alt=""><figcaption><p>Google Ads integration page — connected and healthy</p></figcaption></figure>

{% hint style="info" %}
This integration uses Google Ads' **Enhanced Conversions for Leads (ECL)**. We only ever *upload* conversions — we never touch your campaigns, ad groups, bids, or budgets.
{% endhint %}

***

### What This Solves

Without this integration, Google Ads optimizes toward shallow signals (clicks, form submits) because it has no idea which submissions became paying customers. With it, Google sees the full funnel:

```
Google Ads click  →  Visitor on your site (Ring Tonic tracking)
                              ↓
                     Call / form submission
                              ↓
                       Lead in Ring Tonic
                              ↓
                   Funnel: New → Qualified → Won
                              ↓
                  Ring Tonic uploads to Google Ads:
                  hashed(email/phone) + gclid + value
                              ↓
                Smart Bidding learns: "this keyword
                actually drives paying customers"
```

Net effect: same ad budget, more closed deals, lower cost per closed customer.

***

### Prerequisites

Before connecting, make sure your Google Ads account has all of these:

| Requirement                                                 | Where to set it                                                                                                      |
| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| **Customer data terms accepted**                            | Google Ads → *Tools → Conversions → Settings → Customer data terms* — only an **Admin** on the account can accept    |
| **Enhanced conversions for leads enabled**                  | Google Ads → *Tools → Conversions → Settings → Enhanced conversions for leads* — toggle on                           |
| **At least one lead-type conversion action**                | Google Ads → *Tools → Conversions → Goals* — categories like "Submit lead form", "Phone call lead", "Qualified lead" |
| **Admin or Standard access** for the Google user connecting | Google Ads → *Tools → Admin → Access and security*                                                                   |

{% hint style="warning" %}
**Customer data terms acceptance is a Google-side gate.** If the account isn't set up, Ring Tonic can still connect — but the health check will show **TermsNotAccepted** and you won't be able to create mappings until the Admin accepts the terms inside Google Ads.
{% endhint %}

***

### Connecting Your Google Ads Account

{% stepper %}
{% step %}

#### Navigate to the Integration

Go to **Settings → Google Ads** in Ring Tonic (it's in the Settings sidebar).

<figure><img src="/files/9NkLCpYr8z1ZOzgYe4SN" alt=""><figcaption><p>Google Ads integration page, before connecting</p></figcaption></figure>
{% endstep %}

{% step %}

#### Start the OAuth Flow

Click **Connect**. You'll be redirected to Google's consent screen, signed in with the Google account you want to grant access from.

Review the requested permission:

> **See, edit, create, and delete your Google Ads accounts and data.**

This is the standard `adwords` scope — required for uploading conversions. We don't request any other Google scopes.

Click **Continue** to authorize.

<figure><img src="/files/8rfSS6Vl50GFMvDGEHbv" alt=""><figcaption><p>Google OAuth consent screen</p></figcaption></figure>
{% endstep %}

{% step %}

#### Pick an Account

Ring Tonic lists every Google Ads customer the signed-in user can access. Manager accounts are tagged **\[MCC]**, and sub-customers reached through a manager show the manager ID in the row.

Pick the customer account you want to bind to this workspace, then click **Bind account**.

<figure><img src="/files/2zbejSPhCmUFYxj8tGds" alt=""><figcaption><p>Account picker showing accessible Google Ads customers</p></figcaption></figure>

{% hint style="info" %}
**One Google Ads account per workspace.** If you manage multiple advertisers, each one should have its own Ring Tonic workspace with its own Google Ads binding. This keeps mappings and upload attempts cleanly scoped.
{% endhint %}
{% endstep %}

{% step %}

#### Health Check Runs Automatically

The moment you bind, Ring Tonic queries Google to confirm the account is ready for uploads. The result appears on the integration page — see the [Health Check](#health-check) section below for what each status means.
{% endstep %}
{% endstepper %}

***

### Health Check

The health check verifies that the connected account satisfies Google's prerequisites for Enhanced Conversions for Leads. It runs:

* Immediately after **Bind account**
* When you click **Re-check** on the integration page
* Daily at midnight UTC (background job)
* Just before any upload, if the cached result is stale (>36h)

| Status               | Meaning                                                                         | What to do                                                                                                         |
| -------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| **Ok**               | Terms accepted, ECL enabled. Uploads will go through.                           | Nothing — you're ready to create mappings                                                                          |
| **TermsNotAccepted** | Customer data terms haven't been accepted on this Google Ads account            | An **Admin** on the Google Ads account must accept terms at *Tools → Conversions → Settings → Customer data terms* |
| **EclDisabled**      | Enhanced conversions for leads is off                                           | An Admin must toggle it on at *Tools → Conversions → Settings → Enhanced conversions for leads*                    |
| **Error**            | Google API call failed (developer token issue, account suspended, network blip) | Click Re-check after a few minutes. If it persists, see [Common Issues](#common-issues)                            |

{% hint style="warning" %}
**Mappings are gated by health.** While health is anything other than **Ok**, the mapping editor is disabled and any pending upload jobs skip with `skipped_health_check_failed`. As soon as health goes green and you click Re-check, future uploads resume normally.
{% endhint %}

***

### Default Consent

Google's Consent Mode requires you to send a consent signal for every conversion upload. Ring Tonic resolves consent per upload using this priority:

```
1. Consent attached to the originating form submission
2. Consent from the visitor's session (set by the tracking script)
3. Workspace-level defaults (this section)
```

If neither the form nor the visitor session carries an explicit consent value, Ring Tonic falls back to the workspace defaults set on the integration page. (An `Unspecified` signal from a form or pageview is treated as "no signal" — only an explicit `Granted` / `Denied` overrides these defaults.)

<figure><img src="/files/gGOLDUReaMLXDNTWA0v9" alt=""><figcaption><p>Workspace-level default consent — the fallback when no explicit signal is captured</p></figcaption></figure>

| Signal                 | What it means                                                                       | Recommended default                                                   |
| ---------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| **Ad user data**       | Whether Google can use this conversion to associate with the user's ad interactions | `Granted` if your privacy policy + cookie banner cover ad measurement |
| **Ad personalization** | Whether Google can use this conversion for personalized advertising                 | `Denied` unless you explicitly collect consent for personalization    |

{% hint style="info" %}
Whatever the *resolved* `ad_user_data` value is, if it's **Denied**, Ring Tonic skips the upload entirely (records `skipped_consent_denied`). The conversion never reaches Google, in line with Consent Mode policy.
{% endhint %}

***

### Mapping Stages to Conversion Actions

A mapping says: *"When a contact in this workspace reaches stage X, upload a conversion to this Google Ads conversion action."* Open them from the integration page via **Configure mappings** (breadcrumb: **Settings → Google Ads → Mappings**).

{% stepper %}
{% step %}

#### Pick a Stage

The dropdown shows every Ring Tonic funnel stage that's eligible for upload. `new` is excluded because it's the entry point — only progress through the funnel triggers uploads.

Common picks:

* **Qualified** — lead has been validated by sales
* **Appointment booked** — committed buying intent
* **Won** — the deal closed for actual revenue
  {% endstep %}

{% step %}

#### Pick a Conversion Action

Ring Tonic queries Google Ads and lists every lead-category conversion action in the connected account. Pick the one that should receive uploads for the chosen stage.

<figure><img src="/files/ywVpuvcvVn7YqGFsehXv" alt=""><figcaption><p>Mapping editor — each funnel stage maps to a Google Ads conversion action, with currency and an enable toggle</p></figcaption></figure>

{% hint style="info" %}
**Use distinct conversion actions per stage.** Creating one action for "Qualified Lead" and another for "Closed Deal" lets Google attribute different value to each step in the funnel. Mapping multiple stages to the same action collapses that signal.
{% endhint %}
{% endstep %}

{% step %}

#### Set Value and Currency (Optional)

If you've set a default value on the conversion action in Google Ads, leave this empty and Ring Tonic uses the contact's `deal_value`. If you want to override, enter a fixed value + ISO 4217 currency code.

{% hint style="warning" %}
**Value semantics.** For dynamic per-deal values, leave the mapping value blank and make sure your funnel sets `deal_value` (via form value rules, the Contacts UI, or the CRM Postback API). Ring Tonic will use that. For flat-value events (e.g. "every qualified lead = $50"), enter the value here.
{% endhint %}
{% endstep %}

{% step %}

#### Save

Click **Save mapping**. From this point, every contact that crosses this stage triggers a queued upload. You can disable a mapping at any time without losing it — toggle **Enabled** off.
{% endstep %}
{% endstepper %}

#### What Gets Uploaded

Per upload, Ring Tonic sends to Google Ads:

* **Hashed user identifiers** — SHA-256 of normalized email and phone (lowercased, Gmail dot/+ canonicalization, E.164 phone). Required by ECL — at least one must be present, otherwise the upload skips with `skipped_no_identifiers`.
* **Click IDs** — `gclid` / `gbraid` / `wbraid` if captured by the tracking script when the visitor arrived. Strengthens matching.
* **Conversion action resource** — the one you mapped to the stage.
* **Value + currency** — from mapping or `deal_value`.
* **Conversion time** — when the stage transition happened.
* **Consent flags** — `ad_user_data`, `ad_personalization`.
* **Order ID** — `rt:{workspace}:{contact}:{mapping}:{event}` — Ring Tonic's deduplication key. Re-running the same event won't double-count in Google Ads.

We do **not** send: lead names, transcripts, notes, custom fields, campaign data, or any non-conversion business data.

***

### Viewing Upload Attempts

The **Recent upload attempts** section at the bottom of **Settings → Google Ads** lists every conversion upload Ring Tonic has attempted, with the result and a sanitized payload (no raw PII). Each row shows the status, contact, funnel event, value, which identifiers were sent (email / phone), any click IDs, and the resolved consent signals.

<figure><img src="/files/1mnDjD0zYMy9Fys49AML" alt=""><figcaption><p>Upload attempts — status, contact, value, identifiers, click IDs, and resolved consent per attempt</p></figcaption></figure>

| Status                             | Meaning                                                                                                                                                                                               |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Success**                        | Google accepted the conversion. It'll appear in your Google Ads account's conversions reporting within \~3 hours.                                                                                     |
| **Failed**                         | Google rejected the call. See `error_code` + `error_message` in the row for the specific reason; transient errors are retried automatically up to 3 times with exponential backoff (60s, 5min, 30min) |
| **Skipped — duplicate**            | A successful upload for the same `(event, conversion action)` already exists. Ring Tonic prevents double-counting                                                                                     |
| **Skipped — no identifiers**       | Contact has neither email nor phone, so we can't satisfy ECL's identifier requirement                                                                                                                 |
| **Skipped — consent denied**       | The resolved `ad_user_data` consent was `Denied`, so the upload was suppressed per Consent Mode policy                                                                                                |
| **Skipped — no integration**       | The workspace's Google Ads integration was disconnected between dispatch and execution                                                                                                                |
| **Skipped — health check failed**  | Health was non-Ok at execution time                                                                                                                                                                   |
| **Skipped — mapping disabled**     | The mapping was toggled off or deleted between dispatch and execution                                                                                                                                 |
| **Skipped — mapping changed**      | The mapping was repointed at a different conversion action — Ring Tonic refuses to silently redirect the upload                                                                                       |
| **Skipped — plan feature revoked** | The workspace owner's plan no longer includes Google Ads uploads (job was queued before downgrade)                                                                                                    |

Scroll the table right to reveal the sanitized **Request** and **Response** payload columns — useful for debugging integration issues with your Google Ads admin. Use **Filters** to narrow by status (e.g. show only `Failed`) and **Columns** to choose what's visible.

***

### Common Issues

<details>

<summary>"TermsNotAccepted" — health check keeps showing this</summary>

The Google Ads account hasn't accepted the customer data terms required for Enhanced Conversions for Leads. This is a Google-side gate that can only be unblocked by an **Admin** on the Google Ads account:

1. In Google Ads, go to *Tools → Conversions → Settings*
2. Expand **Customer data terms**
3. Read the policies, tick **I have read and accept the terms on behalf of my company**, save

If the checkbox is greyed out with the message *"Customer data terms for this account must be accepted by an Administrator"*, the currently signed-in Google user doesn't have Admin role on this account. Ask the account owner to either accept the terms themselves or grant you Admin access at *Tools → Admin → Access and security*.

After the terms are accepted, return to Ring Tonic and click **Re-check** — the status should flip to **Ok**.

</details>

<details>

<summary>"EclDisabled" — Enhanced Conversions for Leads is off</summary>

In Google Ads, go to *Tools → Conversions → Settings → Enhanced conversions for leads* and toggle it on. You'll need to choose between the **Google tag** and **Google Tag Manager** implementation paths — pick either, then come back to Ring Tonic and click **Re-check**.

You only need to enable ECL once per Google Ads account. Ring Tonic itself doesn't require any tag installation — we send identifiers via the API, not via a page tag.

</details>

<details>

<summary>"DEVELOPER_TOKEN_NOT_APPROVED" appears in upload errors</summary>

This means Ring Tonic's developer token is not yet approved by Google for production use. Either:

* Ring Tonic is currently using a **Test Account** token — it only works against Google Ads test customer IDs (sandbox accounts), not real accounts. This is the initial state for new Ring Tonic installations; we'll roll out approved tokens during onboarding.
* Or the developer token is pending Basic Access review.

This is a Ring Tonic ops issue, not something you can fix on your side. [Contact support](mailto:support@ringtonic.app) and we'll confirm the developer-token state for your workspace.

</details>

<details>

<summary>"CUSTOMER_NOT_ENABLED" appears in upload errors</summary>

The Google Ads account being uploaded to is cancelled, suspended, or otherwise disabled on Google's side. Common causes:

* Billing failed and the account auto-cancelled
* Google suspended the account for a policy violation
* The account is brand new and hasn't completed signup yet

Resolve the underlying Google Ads account state (billing, policy review, signup completion). Once the account is back to **Enabled** in Google Ads, click **Re-check** in Ring Tonic.

</details>

<details>

<summary>"INVALID_USER_IDENTIFIER" appears in upload errors</summary>

Google rejected the hashed email or phone we sent. Almost always because the source contact has a malformed value — e.g. a non-E.164 phone like `(555) 1234` instead of `+15551234567`, or a missing TLD on the email.

Open the contact, fix the bad identifier, advance the stage again. The next upload will succeed.

</details>

<details>

<summary>Uploads succeed but the conversion never appears in Google Ads reports</summary>

Two things to check:

1. **Wait at least 3 hours** — Google Ads has a delay between conversion upload acceptance and report visibility. Some attribution refresh windows take up to 24 hours.
2. **Check the conversion action's "Include in 'Conversions'" toggle** in Google Ads. If it's off, the conversion is recorded but excluded from the headline Conversions column (and from Smart Bidding learning). This is sometimes intentional (e.g. a test conversion action) — make sure it's on for the action your mapping points to.

</details>

***

### Disconnecting

Click **Disconnect** on the integration page. Ring Tonic immediately:

1. Clears the encrypted refresh token from the workspace
2. Disables all mappings for the workspace (they're kept on disk so you can re-enable after re-connect, but they won't fire while disconnected)
3. Stops dispatching new upload jobs

In-flight upload jobs that were queued before disconnect will skip with `skipped_no_integration` when they run.

To fully revoke Ring Tonic's access on Google's side, go to [myaccount.google.com/permissions](https://myaccount.google.com/permissions) and remove **Ring Tonic** from the list.

***

### Plan Requirements

Google Ads uploads are available on **Pro** and **Agency** plans. If your workspace owner's plan changes mid-flight, any queued upload jobs are evaluated against the current plan at execution time:

* **Plan retained or upgraded** → uploads proceed as normal
* **Plan downgraded** → jobs skip with `skipped_plan_feature_revoked` and the integration stays connected (no data loss; re-upgrade to resume)

***

### Common Questions

<details>

<summary>Does Ring Tonic ever modify my Google Ads campaigns?</summary>

No. The OAuth scope we request (`adwords`) technically grants edit access, but Ring Tonic only calls the conversion upload and metadata read endpoints. We never touch campaigns, ad groups, ads, keywords, bids, budgets, audiences, or any account-level settings.

</details>

<details>

<summary>What's the difference between a "conversion" mapping and a Google Ads campaign goal?</summary>

A **conversion action** is the bucket in Google Ads that holds individual conversion events. A Ring Tonic **mapping** is just our pointer: "when stage X happens, push an event into conversion action Y". One conversion action can be the destination for multiple workspaces; one workspace can map several stages to different conversion actions.

</details>

<details>

<summary>Can I map multiple stages to the same conversion action?</summary>

Technically yes — but you'll lose the per-stage signal. Smart Bidding can't tell that "Qualified Lead" and "Won" represent different funnel depths if both feed the same action. Use distinct conversion actions per stage for the best optimization signal.

</details>

<details>

<summary>What happens if a contact moves backward through the funnel?</summary>

Backward moves don't trigger uploads — Ring Tonic only fires when a stage advances forward. The original event(s) that already uploaded stay in Google Ads (they're real history). If you need to retract a previously uploaded conversion, use Google Ads' conversion adjustments tooling directly.

</details>

<details>

<summary>How does this compare to installing the Google Ads tag on my website?</summary>

The Google Ads tag fires conversions in real time, in the browser, when a page loads (e.g. a "Thank You" page after a form submit). That captures the immediate event but tells Google nothing about what happened to the lead afterward.

Ring Tonic's integration is the **offline conversion** companion: it picks up *after* the form submit and tells Google what actually closed. Most advertisers run both — the page tag for top-of-funnel signal, this integration for downstream value.

</details>

<details>

<summary>Are uploads encrypted in transit?</summary>

Yes. All Google Ads API calls go over HTTPS, and user identifiers (email, phone) are SHA-256 hashed before they leave Ring Tonic — Google never sees raw PII.

</details>

<details>

<summary>How long does Ring Tonic keep my refresh token?</summary>

Until you click **Disconnect** or revoke access at [myaccount.google.com/permissions](https://myaccount.google.com/permissions). The token is encrypted at rest with the workspace's encryption key.

</details>

<details>

<summary>What's the daily upload limit?</summary>

Ring Tonic's developer token is approved for **Basic Access** (15,000 API operations per day across all workspaces). Each conversion upload counts as one operation. This ceiling is sufficient for the vast majority of workspaces — if you're approaching it, contact support and we'll review your usage.

</details>

***

### Related Guides

* [Contacts](/guides/contacts.md) — the funnel view that drives stage transitions
* [Form Submissions](/guides/form-submissions.md) — how Ring Tonic captures the original lead and its click ID
* [CRM Postback API](/guides/crm-api.md) — push external events that advance the funnel (and trigger Google Ads uploads)
* [How to Ensure 100% Attribution Accuracy](/guides/how-to-ensure-100-attribution-accuracy.md) — what the tracking script needs to capture for ECL to work


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://help.ringtonic.app/guides/google-ads-integration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
