{"id":471,"date":"2026-09-16T08:40:00","date_gmt":"2026-09-16T06:40:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/?p=471"},"modified":"2026-10-26T12:38:55","modified_gmt":"2026-10-26T11:38:55","slug":"sending-purchase-values-from-bigquery-to-google-ads","status":"publish","type":"post","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/","title":{"rendered":"Sending Purchase Values from BigQuery to Google Ads"},"content":{"rendered":"<p>Google Ads can optimize bids using conversion values supplied by a business. BigQuery can prepare those values from order data, for example a contribution margin after defined variable costs. For example, 100 euros of revenue excluding tax minus 60 euros of goods, shipping and payment costs leaves 40 euros of contribution margin. Fixed costs are not yet deducted. This is not automatically net profit, cash flow or customer lifetime value. A useful pipeline needs a documented value definition, permitted data use, reliable identifiers and a separate upload process.<\/p>\n<p>OCI means Offline Conversion Import: a recorded business outcome is sent to Google Ads after the event.<\/p>\n<figure class=\"lw-diagram\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/dia-471-review-20261024.png\" width=\"1120\" height=\"580\" alt=\"Order data passes explicit checks before import. Accepted results and later adjustments require separate processing.\"><figcaption>Order data passes explicit checks before import. Accepted results and later adjustments require separate processing.<\/figcaption><\/figure>\n<h2>What the pipeline does<\/h2>\n<p>The example below prepares classic GCLID-based offline conversions. It links an order to a captured ad click; it does not calculate a multi-touch attribution model. GA4 is optional for this design. The standard GA4 export includes <code>ecommerce.transaction_id<\/code> and event-level <code>collected_traffic_source.gclid<\/code>, but a purchase event is not guaranteed to contain a custom <code>gclid<\/code> parameter.<\/p>\n<p>Click-ID capture and advertising uploads require the applicable consent and policy checks. A first-party cookie or an ERP record does not bypass those requirements. The example uses a previously validated <code>marketing_upload_allowed<\/code> flag. That flag is an internal gate, not a replacement for consent evidence or the upload API\u2019s consent fields.<\/p>\n<h2>Required fields and their meaning<\/h2>\n<ul>\n<li><code>orders_for_ads<\/code> contains one current row per <code>order_id<\/code>. The ID is stable and non-empty; duplicate rows are flagged rather than silently selected.<\/li>\n<li><code>gclid<\/code> is the original captured identifier. <code>click_time<\/code> and <code>conversion_time<\/code> are TIMESTAMP fields; the conversion time is the actual, immutable business event, not the time of a retry.<\/li>\n<li><code>net_revenue_ex_tax<\/code>, <code>cogs_amount<\/code>, <code>shipping_cost<\/code> and <code>payment_fee<\/code> are NUMERIC amounts in the same currency. Revenue reflects discounts and known refunds. Costs must use consistent signs and refund treatment.<\/li>\n<li><code>currency_code<\/code> is a validated ISO 4217 currency. The query only checks the three-letter format, not membership in the ISO list.<\/li>\n<li><code>marketing_upload_allowed<\/code> is BOOL. <code>order_status<\/code> follows the shop\u2019s documented lifecycle. <code>ads_upload_log<\/code> records accepted imports with order ID, action and BOOL <code>accepted<\/code>; rejected requests do not count as accepted.<\/li>\n<\/ul>\n<p>The example assumes one Google Ads conversion customer and one action mapping. Multiple accounts require that account identity in the import ledger key. Financial values must be finite NUMERIC amounts. Parallel upload workers also need coordination or an idempotent sender that repeats requests without duplicate effects; checking the ledger is not a lock.<\/p>\n<h2>Preparing and checking orders before upload<\/h2>\n<p>The following GoogleSQL example retains pending historical orders, so shipment on day eight does not lose an order from a seven-day purchase window. For production use, tables need suitable partitions, for example by date, so each run does not read the entire history. Incremental reconciliation processes new or changed orders while also keeping track of older pending orders. The 30-day action window is an example setting that must match the conversion action.<\/p>\n<pre class=\"wp-block-code-beautifier-block-code\"><code>-- GoogleSQL teaching example: replace project\/dataset identifiers.\n-- orders_for_ads: one current row per order; timestamps remain immutable.\n-- ads_upload_log: accepted imports only, keyed by action + order_id.\nDECLARE run_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP();\nDECLARE action_name STRING DEFAULT &#x27;Contribution_Purchase&#x27;;\n-- Example only: match the configured conversion action&#x27;s click window.\nDECLARE click_window_days INT64 DEFAULT 30;\n\nWITH prepared AS (\n  SELECT o.*,\n    COUNT(*) OVER (PARTITION BY order_id) AS rows_per_order,\n    ROUND(net_revenue_ex_tax - cogs_amount - shipping_cost - payment_fee, 2)\n      AS contribution_value,\n    EXISTS (\n      SELECT 1 FROM `project_id.erp_data.ads_upload_log` AS l\n      WHERE l.order_id = o.order_id AND l.conversion_action = action_name\n        AND l.accepted = TRUE\n    ) AS already_imported\n  FROM `project_id.erp_data.orders_for_ads` AS o\n),\nclassified AS (\n  SELECT *,\n    CASE\n      WHEN order_id IS NULL OR TRIM(order_id) = &#x27;&#x27; OR rows_per_order != 1\n        THEN &#x27;INVALID_ORDER_KEY&#x27;\n      WHEN already_imported THEN &#x27;ALREADY_IMPORTED_CHECK_ADJUSTMENTS&#x27;\n      WHEN marketing_upload_allowed IS NOT TRUE THEN &#x27;CONSENT_NOT_CLEARED&#x27;\n      WHEN order_status != &#x27;PAID_AND_SHIPPED&#x27; OR order_status IS NULL\n        THEN &#x27;NOT_READY&#x27;\n      WHEN gclid IS NULL OR TRIM(gclid) = &#x27;&#x27; THEN &#x27;MISSING_GCLID&#x27;\n      WHEN conversion_time IS NULL OR click_time IS NULL\n        OR conversion_time &lt;= click_time OR conversion_time &gt; run_time\n        THEN &#x27;INVALID_TIME&#x27;\n      WHEN click_time &lt; TIMESTAMP_SUB(run_time, INTERVAL 90 DAY)\n        THEN &#x27;IMPORT_TOO_LATE&#x27;\n      WHEN conversion_time &gt; TIMESTAMP_ADD(click_time, INTERVAL click_window_days DAY)\n        THEN &#x27;OUTSIDE_ACTION_WINDOW&#x27;\n      WHEN contribution_value IS NULL THEN &#x27;MISSING_FINANCIALS&#x27;\n      WHEN currency_code IS NULL OR NOT REGEXP_CONTAINS(currency_code, r&#x27;^[A-Z]{3}$&#x27;)\n        THEN &#x27;INVALID_CURRENCY_FORMAT&#x27;\n      ELSE &#x27;READY&#x27;\n    END AS staging_status\n  FROM prepared\n)\nSELECT order_id, gclid, action_name AS conversion_action,\n  FORMAT_TIMESTAMP(&#x27;%Y-%m-%d %H:%M:%S+00:00&#x27;, conversion_time, &#x27;UTC&#x27;)\n    AS conversion_date_time,\n  contribution_value,\n  -- Explicit business policy: losses become zero bidding value, not omitted orders.\n  GREATEST(contribution_value, 0) AS conversion_value,\n  currency_code, staging_status\nFROM classified;\n<\/code><\/pre>\n<p>The example rounds values to two decimal places, as appropriate for its EUR\/USD-style amount convention; other currency precision rules require adaptation.<\/p>\n<p>Only rows with <code>staging_status = 'READY'<\/code> are upload candidates. Other statuses need monitoring and, where appropriate, correction or later retries. Even READY does not confirm that Google Ads will accept or attribute a conversion. Missing amounts remain errors instead of silently becoming zero.<\/p>\n<p>The example deliberately maps negative contribution margins to a bidding value of zero while retaining the signed amount for reporting. This is a business rule, not a claim that losses disappear. A different value policy needs its own design. No arbitrary LTV multiplier is added; predictions require a separately validated model.<\/p>\n<p><!-- lw-flux-illu 471-a3 --><\/p>\n<figure class=\"lw-illu\"><img src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/illustrationen\/flux-471-a3.webp\" width=\"1120\" height=\"630\" loading=\"lazy\" decoding=\"async\" alt=\"Today&#039;s driftwood is loaded on the cart, and an older branch left above yesterday&#039;s tide line goes on top too. Likewise, older orders that are still open are kept for the upload instead of being dropped.\"><figcaption>Today&#039;s driftwood is loaded on the cart, and an older branch left above yesterday&#039;s tide line goes on top too. Likewise, older orders that are still open are kept for the upload instead of being dropped.<\/figcaption><\/figure>\n<h2>Connection and operation<\/h2>\n<ol>\n<li><strong>Upload path:<\/strong> Google Ads Data Manager supports a direct BigQuery connection with permissions and field mapping. The Google Ads connector in BigQuery Data Transfer Service moves reporting data in the opposite direction, into BigQuery; a scheduled query alone sends no conversions.<\/li>\n<li><strong>Action and payload mapping:<\/strong> the Ads API requires the resource name of an enabled <code>UPLOAD_CLICKS<\/code> action. The SQL action label therefore needs mapping. Order ID, GCLID, conversion time, value, currency and applicable consent fields need mapping to the chosen interface; CSV, Data Manager and API field names are not interchangeable.<\/li>\n<li><strong>Result records:<\/strong> request identity, stable order\/action\/time, accepted result, individual errors and retry state need recording. Partial failures require separate handling; an HTTP success alone does not prove that every row succeeded. Time windows need another check when a queued row is actually sent.<\/li>\n<li><strong>Change reconciliation:<\/strong> previously accepted orders go to a separate adjustment process for refunds or corrected values. A repeat original import is not a value update. The upload ledger needs reconciliation with backend orders and Google Ads diagnostics.<\/li>\n<li><strong>Bidding introduction:<\/strong> the action initially serves observation, with campaign goals under review. Secondary actions can still affect bidding inside custom goals. Validation should cover data volume, financial reconciliation and conversion delays; fourteen days is not a universal readiness certificate. Unintentional bidding on both revenue and contribution value for the same order would double-count the business outcome.<\/li>\n<\/ol>\n<h2>Timing and identifier boundaries<\/h2>\n<p>Google documents a maximum upload age of 90 days after the associated click for classic offline imports, versus 63 days for enhanced conversions for leads. The conversion action\u2019s own window also applies. There is no universal rule requiring every upload to wait 24 hours. Recent-click processing can cause temporary errors; the scheduled-upload FAQ recommends allowing six hours in that case. The original conversion timestamp must remain unchanged during retries.<\/p>\n<p>This example intentionally handles GCLID only. GBRAID and WBRAID require the appropriate fields and supported workflow, not a generic COALESCE into a GCLID column. The current Ads API adjustment documentation supports GCLID and GBRAID adjustments but excludes WBRAID adjustments. Identifier choice therefore also affects the refund design.<\/p>\n<div class=\"lw-faq\">\n<h2>Questions and answers<\/h2>\n<h3>Does an order ID prevent every duplicate?<\/h3>\n<p>A stable order ID per action helps Google Ads deduplicate imports and reference adjustments. Internal uniqueness checks and an accepted-upload ledger are still necessary. A second conversion action can count the same order separately.<\/p>\n<h3>How are later refunds represented?<\/h3>\n<p>Supported conversions use <code>RESTATEMENT<\/code> for a revised value or <code>RETRACTION<\/code> for removal, subject to the method\u2019s rules and deadlines. If the original import included an order ID, adjustments must use that ID. Restating to zero or retracting can prevent further adjustments, so the correction workflow needs explicit handling.<\/p>\n<h3>Does margin-based bidding guarantee better ROAS?<\/h3>\n<p>No. Data quality, delays, campaign settings and the chosen value model affect results. Conversion value divided by ad spend expresses the uploaded metric; a margin-based ratio is not revenue ROAS and does not measure total business profit.<\/p>\n<\/div>\n<div class=\"lw-quellen\">\n<h2>Sources<\/h2>\n<ul>\n<li><a href=\"https:\/\/docs.cloud.google.com\/bigquery\/docs\" target=\"_blank\" rel=\"noopener noreferrer\">BigQuery documentation<\/a><\/li>\n<li><a href=\"https:\/\/developers.google.com\/google-ads\/api\/docs\/get-started\/introduction\" target=\"_blank\" rel=\"noopener noreferrer\">Google Ads API documentation<\/a><\/li>\n<li><a href=\"https:\/\/support.google.com\/analytics\/answer\/7029846\" target=\"_blank\" rel=\"noopener noreferrer\">GA4 export schema<\/a><\/li>\n<li><a href=\"https:\/\/support.google.com\/google-ads\/answer\/13763054\" target=\"_blank\" rel=\"noopener noreferrer\">BigQuery connection in Data Manager<\/a><\/li>\n<li><a href=\"https:\/\/docs.cloud.google.com\/bigquery\/docs\/google-ads-transfer\" target=\"_blank\" rel=\"noopener noreferrer\">Google Ads reports into BigQuery<\/a><\/li>\n<li><a href=\"https:\/\/developers.google.com\/google-ads\/api\/docs\/conversions\/upload-offline\" target=\"_blank\" rel=\"noopener noreferrer\">Offline conversion imports<\/a><\/li>\n<li><a href=\"https:\/\/support.google.com\/google-ads\/answer\/15081888\" target=\"_blank\" rel=\"noopener noreferrer\">Offline import timing<\/a><\/li>\n<li><a href=\"https:\/\/support.google.com\/google-ads\/answer\/10029210\" target=\"_blank\" rel=\"noopener noreferrer\">Offline import FAQ<\/a><\/li>\n<li><a href=\"https:\/\/developers.google.com\/google-ads\/api\/docs\/conversions\/upload-adjustments\" target=\"_blank\" rel=\"noopener noreferrer\">Conversion adjustments and identifiers<\/a><\/li>\n<li><a href=\"https:\/\/support.google.com\/google-ads\/answer\/7686447\" target=\"_blank\" rel=\"noopener noreferrer\">Adjustment behavior<\/a><\/li>\n<li><a href=\"https:\/\/support.google.com\/google-ads\/answer\/11461796\" target=\"_blank\" rel=\"noopener noreferrer\">Primary and secondary actions<\/a><\/li>\n<li><a href=\"https:\/\/www.google.com\/about\/company\/user-consent-policy-help\/\" target=\"_blank\" rel=\"noopener noreferrer\">Google consent policy<\/a><\/li>\n<li><a href=\"https:\/\/support.google.com\/google-ads\/answer\/13802165\" target=\"_blank\" rel=\"noopener noreferrer\">Consent mode reference<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>A BigQuery example prepares contribution-margin values for GCLID-based offline conversion imports into Google Ads. The article explains data checks, separate uploads, retries and refunds; the query does not calculate profit or customer lifetime value.<\/p>\n","protected":false},"author":1,"featured_media":30579,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[127],"tags":[91383,91333,91261,91386,91288,91219],"class_list":["post-471","post","type-post","status-publish","format-standard","hentry","category-tutorials-en-digital-marketing","tag-attribution","tag-bigquery","tag-conversion-tracking","tag-marketing-cyfrowy-pl","tag-google-ads","tag-tutorial"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Sending Purchase Values from BigQuery to Google Ads | Lukas Wojcik<\/title>\n<meta name=\"description\" content=\"Send BigQuery data to Google Ads OCI: profit and LTV models, SQL preparation, automated uploads and handling returned orders.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Sending Purchase Values from BigQuery to Google Ads | Lukas Wojcik\" \/>\n<meta property=\"og:description\" content=\"Send BigQuery data to Google Ads OCI: profit and LTV models, SQL preparation, automated uploads and handling returned orders.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-16T06:40:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-26T11:38:55+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/11\/klarheit-20261111-471.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Lukas Wojcik\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lukas Wojcik\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/\"},\"author\":{\"name\":\"Lukas Wojcik\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"headline\":\"Sending Purchase Values from BigQuery to Google Ads\",\"datePublished\":\"2026-09-16T06:40:00+00:00\",\"dateModified\":\"2026-10-26T11:38:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/\"},\"wordCount\":1156,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/klarheit-20261111-471.png\",\"keywords\":[\"Attribution\",\"BigQuery\",\"Conversion Tracking\",\"Digital Marketing\",\"Google Ads\",\"Tutorial\"],\"articleSection\":[\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/\",\"name\":\"Sending Purchase Values from BigQuery to Google Ads | Lukas Wojcik\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/klarheit-20261111-471.png\",\"datePublished\":\"2026-09-16T06:40:00+00:00\",\"dateModified\":\"2026-10-26T11:38:55+00:00\",\"description\":\"Send BigQuery data to Google Ads OCI: profit and LTV models, SQL preparation, automated uploads and handling returned orders.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/klarheit-20261111-471.png\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/klarheit-20261111-471.png\",\"width\":1200,\"height\":630,\"caption\":\"Sending Purchase Values from BigQuery to Google Ads\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/tutorials-en-digital-marketing\\\/sending-purchase-values-from-bigquery-to-google-ads\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Sending Purchase Values from BigQuery to Google Ads\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Sending Purchase Values from BigQuery to Google Ads | Lukas Wojcik","description":"Send BigQuery data to Google Ads OCI: profit and LTV models, SQL preparation, automated uploads and handling returned orders.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/","og_locale":"en_US","og_type":"article","og_title":"Sending Purchase Values from BigQuery to Google Ads | Lukas Wojcik","og_description":"Send BigQuery data to Google Ads OCI: profit and LTV models, SQL preparation, automated uploads and handling returned orders.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/","og_site_name":"Lukas Wojcik - Blog","article_published_time":"2026-09-16T06:40:00+00:00","article_modified_time":"2026-10-26T11:38:55+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/11\/klarheit-20261111-471.png","type":"image\/png"}],"author":"Lukas Wojcik","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Lukas Wojcik","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/#article","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/"},"author":{"name":"Lukas Wojcik","@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"headline":"Sending Purchase Values from BigQuery to Google Ads","datePublished":"2026-09-16T06:40:00+00:00","dateModified":"2026-10-26T11:38:55+00:00","mainEntityOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/"},"wordCount":1156,"commentCount":0,"publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/11\/klarheit-20261111-471.png","keywords":["Attribution","BigQuery","Conversion Tracking","Digital Marketing","Google Ads","Tutorial"],"articleSection":["Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/","name":"Sending Purchase Values from BigQuery to Google Ads | Lukas Wojcik","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/#primaryimage"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/11\/klarheit-20261111-471.png","datePublished":"2026-09-16T06:40:00+00:00","dateModified":"2026-10-26T11:38:55+00:00","description":"Send BigQuery data to Google Ads OCI: profit and LTV models, SQL preparation, automated uploads and handling returned orders.","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/#primaryimage","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/11\/klarheit-20261111-471.png","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/11\/klarheit-20261111-471.png","width":1200,"height":630,"caption":"Sending Purchase Values from BigQuery to Google Ads"},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/tutorials-en-digital-marketing\/sending-purchase-values-from-bigquery-to-google-ads\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Sending Purchase Values from BigQuery to Google Ads"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/471","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=471"}],"version-history":[{"count":9,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/471\/revisions"}],"predecessor-version":[{"id":26972,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/471\/revisions\/26972"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media\/30579"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=471"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/categories?post=471"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=471"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}