Skip to content

BigQuery v1 Integration (Deprecated)

Google BigQuery is a fast, scalable, and fully managed cloud data warehouse designed for analytics. By integrating CustomerLabs with BigQuery, you can build your own marketing data lake — centralizing all customer event data in one place for analysis, reporting, and attribution.

CustomerLabs sends your event data directly to BigQuery with no code required.


Before you begin, ensure you have:

  • A Google Cloud Platform (GCP) account
  • A GCP project with the BigQuery API enabled
  • Billing enabled on the project
  • A CustomerLabs account

The integration involves four steps — three in GCP and one in CustomerLabs:

  1. Locate your Project ID and verify the BigQuery API is enabled.
  2. Grant access to the CustomerLabs service account via IAM.
  3. Enable billing on your GCP project.
  4. Paste your Project ID into CustomerLabs to complete the connection.

Step 1: Get Your Project ID and Verify BigQuery API

Section titled “Step 1: Get Your Project ID and Verify BigQuery API”
  1. Log in to Google Cloud Platform.

  2. Click the project selector at the top. Your Project ID is listed in the ID column next to the project name.

    GCP project list showing Project IDs

    Copy the Project ID — you will need it in Step 4.

  3. Verify that the BigQuery API is enabled. Go to APIs & ServicesLibrary, search for “BigQuery API”, and confirm the status shows API Enabled.

    BigQuery API page showing API Enabled status

Step 2: Grant Access to CustomerLabs (IAM)

Section titled “Step 2: Grant Access to CustomerLabs (IAM)”

CustomerLabs writes data to your BigQuery project using a dedicated service account. You need to grant that service account the appropriate roles.

  1. In GCP, navigate to IAM & AdminIAM. Select your project, then click + Grant Access.

    GCP IAM page with Grant Access button highlighted
  2. In the New principals field, paste the CustomerLabs service account ID:

    Grant access panel with CustomerLabs service account entered
  3. Assign the following two roles, then click Save:

    • BigQuery Data Owner
    • BigQuery Job User

BigQuery requires an active billing account to process data jobs.

  1. In GCP, navigate to Billing from the left sidebar.

  2. If billing is not active, click Link a Billing Account and follow the prompts.

    GCP Billing page showing Link a Billing Account option
  3. Confirm the billing status is Active before proceeding.


  1. Log in to your CustomerLabs account and navigate to Destinations.

  2. Search for and select BigQuery.

    CustomerLabs All Destinations page with BigQuery highlighted
  3. Enter a Destination ID and click Save and Enable.

    Save and Enable BigQuery destination modal
  4. Click Configuration settings.

    BigQuery Customization screen with Configuration settings highlighted
  5. Paste the Project ID you copied earlier into the Google Project ID field and click Save Changes.


CustomerLabs creates three tables in your BigQuery dataset:

TablePurpose
events_dataAll event-level data from your website
users_dataKnown user profiles
anonymous_users_dataMaps anonymous IDs to known user IDs

Stores all tracked events. Top-level fields:

FieldTypeDescription
screen_sizeSTRINGUser’s screen resolution (e.g., 1920 x 1080)
platformSTRINGOperating system (e.g., Windows 10, Mac OS X10)
countrySTRINGDerived from IP (e.g., India, United States)
citySTRINGDerived from IP (e.g., Chennai, Saint Paul)
stateSTRINGDerived from IP (e.g., Tamil Nadu, Minnesota)
postal_codeSTRINGDerived from IP (e.g., 500044)
continentSTRINGDerived from IP (e.g., Asia, North America)
visitor_typeSTRINGNew or Returning
session_idSTRINGSession identifier (e.g., CL-5bh3y984u23uefhf)
sourceSTRINGTraffic source (e.g., direct, google search)
source_typeSTRINGTraffic type (e.g., organic, unknown)
page_titleSTRINGTitle of the visited page
page_urlSTRINGURL of the visited page
deviceSTRINGmobile device or desktop
ip_addressSTRINGUser’s IP address
locationSTRINGLat/long derived from IP (e.g., 37.7510, -97.8220)
timezoneSTRINGDerived from IP (e.g., Asia/Kolkata)
FieldNested SchemaDescription
user_traitskey, value (STRING)Profile attributes: first_name, last_name, email, phone_number, etc.
group_traitskey, value (STRING)Reserved for future use
cl_utm_paramskey, value (STRING)UTM parameters: utm_source, utm_medium, utm_campaign, etc.
cl_other_paramskey, value (STRING)All non-UTM URL query parameters (e.g., gclid, user-agent)
event_attributeskey, value, type (STRING)Event context: event_from, event_source, event_status
productsproduct_traitskey, value, type (STRING)Product details for e-commerce events
external_idskey, value, type (STRING)Cross-platform IDs: GA client ID, _fbp, _fbc, customerlabs_user_id
group_external_idskey, value, type (STRING)Reserved for future use
additional_infokey, value (STRING)Device, browser, session, and first interaction metadata
segmentssegment_id, segment_name, added_atReserved for future use

Stores known user profiles.

FieldTypeDescription
user_idSTRINGCustomerLabs user ID
inserted_atTIMESTAMPTime the record was ingested

Nested fields: traits, external_ids, additional_info, segments — same schema as events_data.


Maps anonymous visitors to their resolved user IDs.

FieldTypeDescription
user_idSTRINGKnown CustomerLabs user ID
anonymous_user_idSTRINGAnonymous ID assigned before identification
inserted_atTIMESTAMPTime the record was ingested

[
{ "key": "email", "value": "[email protected]" },
{ "key": "first_name", "value": "test" },
{ "key": "last_name", "value": "last" }
]
[
{ "key": "utm_source", "value": "google" },
{ "key": "utm_medium", "value": "cpc" },
{ "key": "utm_campaign", "value": "summer_sale" }
]
[
{ "key": "gad_source", "value": "2" },
{ "key": "gclid", "value": "Cxfgcgyugyhuivdshue89732r89uy298..." },
{ "key": "user-agent", "value": "Mozilla/5.0 (Linux; Android 10; K)..." }
]
[
{ "key": "event_from", "value": "website" },
{ "key": "event_source", "value": "js_helper" },
{ "key": "event_status", "value": "active" }
]
[
[
{ "key": "product_id", "value": "1", "type": "number" },
{ "key": "product_name", "value": "Blue T-Shirt", "type": "string" },
{ "key": "product_price", "value": "100", "type": "number" }
],
[
{ "key": "product_id", "value": "2", "type": "number" },
{ "key": "product_name", "value": "Black Jeans", "type": "string" },
{ "key": "product_price", "value": "200", "type": "number" }
]
]
[
{ "key": "client_id", "value": "js8628376773", "type": "google_analytics" },
{ "key": "_fbc", "value": "js786486283752523", "type": "facebook" }
]

Returns a count of how many times each user triggered a specific event.

SELECT user_id, count(user_id)
FROM `[Dataset Id].events_data`
WHERE action = "pageview"
GROUP BY user_id

Query 2 — Identity Resolution: Merge Anonymous + Known Users

Section titled “Query 2 — Identity Resolution: Merge Anonymous + Known Users”

Stitches anonymous visitors to their resolved user IDs and counts events per unified user.

WITH
anonymous_user_list AS (
SELECT user_id, anonymous_user_id FROM (
SELECT user_id, anonymous_user_id,
ROW_NUMBER() OVER(PARTITION BY anonymous_user_id ORDER BY inserted_at DESC) AS top
FROM `[Dataset Id].anonymous_users_data`
) WHERE top = 1
)
SELECT user_id, count(user_id) FROM (
SELECT IFNULL(aul.user_id, t0.user_id) AS user_id
FROM `[Dataset Id].events_data` t0
LEFT JOIN anonymous_user_list AS aul ON aul.anonymous_user_id = t0.user_id
WHERE action = "pageview"
) GROUP BY user_id

Query 3 — Get Full User Profiles for an Event

Section titled “Query 3 — Get Full User Profiles for an Event”

Retrieves complete user profile data for everyone who performed a specific event (e.g., Added to cart), with identity resolution applied.

WITH
anonymous_user_list AS (
SELECT user_id, anonymous_user_id FROM (
SELECT user_id, anonymous_user_id,
ROW_NUMBER() OVER(PARTITION BY anonymous_user_id ORDER BY inserted_at DESC) AS top
FROM `[Dataset Id].anonymous_users_data`
) WHERE top = 1
),
event_users_list AS (
SELECT user_id FROM (
SELECT IFNULL(aul.user_id, t0.user_id) AS user_id
FROM `[Dataset Id].events_data` t0
LEFT JOIN anonymous_user_list AS aul ON aul.anonymous_user_id = t0.user_id
WHERE action = "Added to cart"
) GROUP BY user_id
),
users_master AS (
SELECT * FROM (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY inserted_at DESC) AS top
FROM `[Dataset Id].users_data`
) WHERE top = 1
)
SELECT * FROM event_users_list AS eul
INNER JOIN users_master AS um ON eul.user_id = um.user_id