# Receive zero-party data in BigQuery

Connect a BigQuery dataset in Settings > Data Sources. Brand Control Center creates a genuin_data table and fills it with your social experience's event rows on a daily, weekly, or monthly schedule.

Your social experience generates zero-party data: what members watch, search for, join, post, react to, and click. Members produce it by taking part, not by being tracked across other sites. [How zero-party data powers your social experience and media revenue](https://begenuin.com/developers/browse-by-products/control/how-zero-party-data-powers-brand-communities-and-media-revenue-without-compromising-consumer-trust) explains the model. This page shows how to land that data in your own warehouse, where you own it and can join it with the rest of your business data.

## What arrives in BigQuery

Brand Control Center creates one table, `genuin_data`, in the dataset you name. It never creates a second table or writes anywhere else in your project. Each row is one event from your apps, embeds, and communities, timestamped in UTC. The table has 145 nullable columns in seven groups.

| Group | Example columns | What it tells you |
| --- | --- | --- |
| Event | _timestamp, event, brand_id, content_id, content_type, conv_type | What happened, when, and to which piece of content |
| Member intent | topic_ids, communities_selected, keyword_searched, search_source, question, selected_option | Interests chosen, searches run, prompts answered |
| Watching and posting | video_view_length, length_at_video_paused, video_duration, upload_video_length, link_added | How much of a video was watched, how long a post ran, whether a link-out was added |
| App and device context | context_app_name, context_app_version, context_os_name, context_device_model, context_session_id, context_timezone, country_code | Where the event came from, grouped by session |
| Campaign | utm_source, utm_medium, utm_campaign, campaign, media_source, embed_id | Which campaign or embed brought the member in |
| Content records | master_video_, master_community_, master_loops_, master_groups_, master_brand_ | The video, community, loop, group, and brand the event refers to, joined in so you don't have to |
| Comment and share records | master_c_video_, master_c_user_uuid, master_c_community_, master_s_user_uuid | For comments and shares, the video commented on and the member who shared |

The `master_*` columns are joined from Genuin's own records, so a single `WHERE master_community_handle = 'running'` filter works without a second table. Rows are written in batches on the schedule you choose, not in real time.

## Before you begin

- **A Google Cloud project with a BigQuery dataset** that will hold the table. Note the project ID and dataset name. You enter them as one value, `project_id.dataset_name`.
- **An account for the connection.** A Service account is the right choice for a production warehouse, because its access is scoped to one dataset and survives staff changes. A User account signs in with Google and needs permission to create, update, and list tables in the dataset.
- **Edit access to Data Sources** in Brand Control Center. A role with view-only access sees the form disabled.

## Step 1: Give a service account the BigQuery Data Editor role

Skip steps 1 and 2 if you'll sign in with a User account.

1. In Google Cloud, open **IAM & Admin > Service Accounts** and create a service account for the connection. Create a JSON key for it and download the file.
2. Open **IAM**, find the service account, and open **Edit access**.
3. Under **Assign roles**, pick **BigQuery Data Editor**. The role lets the connection create the table and append rows.
   ![The Edit access panel in Google Cloud IAM shows the service account with the BigQuery Data Editor role selected.](https://cdn.sanity.io/images/lnrtvsvr/development/37ae57bc931fbc17ac2d5992405e624ec898b068-1650x845.jpg)
   *BigQuery Data Editor is the only role the connection needs.*

## Step 2: Limit the role to one dataset

1. Still in **Edit access**, add an **IAM condition** to the role.
2. In the condition builder, add two rules joined with AND:
   - **Service** is `bigquery.googleapis.com`
   - **Name** starts with `projects/<project_id>/datasets/<dataset_name>`
3. Save the condition, then save the role.
   ![The IAM condition builder shows a Service rule set to bigquery.googleapis.com and a Name rule that starts with the dataset's resource path.](https://cdn.sanity.io/images/lnrtvsvr/development/ece247f041dbae42f955c94d25dd9ea0999392f0-1650x836.jpg)
   *Two rules limit the service account to the one dataset Brand Control Center writes to.*

With the condition in place, the service account has no access to any other dataset in the project.

## Step 3: Open the BigQuery data source

1. In Brand Control Center, open **Settings > Data Sources**.
2. Expand **BigQuery**. The panel sits below S3 Storage and Mix Panel.
   ![The Data Sources page in Settings with the BigQuery panel expanded, showing Account type, Dataset ID, and Data Sync Frequency fields.](https://cdn.sanity.io/images/lnrtvsvr/development/369b0a67ef61627a137950d5a116d1103b9a28f5-1650x747.jpg)
   *The BigQuery panel before a connection. Account type defaults to User.*

## Step 4: Connect the dataset

Fill the three fields, then connect with the account type you chose.

| Field | Value |
| --- | --- |
| Account type | User or Service. Locked once connected. |
| Dataset ID | project_id.dataset_name. Letters, digits, hyphens, and underscores, with exactly one dot. |
| Data Sync Frequency | Daily, Weekly, or Monthly. The only setting you can change later. |

### User account

1. Pick **User**, enter the Dataset ID, and pick a frequency.
2. Select **Sign in with Google** and approve the request. The consent screen asks for your email, profile, and BigQuery access.
   ![The BigQuery panel with Account type User, a Dataset ID entered, and the Sign in with Google button highlighted.](https://cdn.sanity.io/images/lnrtvsvr/development/391a7056661e8596e6577261d8c683225a3c9e1c-1650x747.jpg)
   *With a User account, the Google sign-in completes the connection.*

### Service account

1. Pick **Service**, enter the Dataset ID, and pick a frequency.
2. Under **Upload JSON File**, upload the key file from step 1. The file has to be a service account key under 10 KB, and the form reads the project ID and key ID from it.
3. Select **Connect**.
   ![The BigQuery panel with Account type Service, the uploaded key file listed, and the Connect button highlighted.](https://cdn.sanity.io/images/lnrtvsvr/development/f796ee58cdff856220950b9a4e1206f0095d71fe-1650x747.jpg)
   *The Connect button becomes active once the Dataset ID, frequency, and key file are in place.*

On connect, Brand Control Center lists the tables in the dataset. If `genuin_data` is missing, it creates the table with the schema above. If the table is already there, from an earlier connection, it keeps it and appends to it. A notification confirms the connection, the banner names the table, and the Dataset ID and Account type lock.

![The BigQuery panel after connecting, with a success notification, a locked Dataset ID, and a Disconnect button.](https://cdn.sanity.io/images/lnrtvsvr/development/0ecb066cf20a59d1d675fc809388772392658f93-1650x747.jpg)
*Once connected, the banner points to genuin_data and only the frequency stays editable.*

If the connection fails, the usual cause is permissions. The user or service account lacks create, update, or list rights on the dataset, or the IAM condition names a different dataset.

## Step 5: Query the table

Open the dataset in the BigQuery console. The `genuin_data` table appears under it, with the schema ready before the first rows arrive.

![The BigQuery console shows the genuin_data table under the dataset, with its schema listing _timestamp, brand_id, build, channel, and more.](https://cdn.sanity.io/images/lnrtvsvr/development/b524953e2a69b23d2fd5605a02d6d6f1eec4b1f4-1650x747.jpg)
*The table and its 145 columns exist as soon as the connection succeeds.*

Rows land on the schedule you picked. A first query that shows which events arrived in the past week:

```sql title="Events per day"
SELECT
  DATE(_timestamp) AS day,
  event,
  COUNT(*) AS events
FROM `project_id.dataset_name.genuin_data`
WHERE _timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
GROUP BY day, event
ORDER BY day DESC, events DESC;
```

From there, join on `master_video_uuid` or `master_community_uuid` to your own catalogue, or on `utm_campaign` to your campaign table.

## Change the sync frequency

1. Open **Settings > Data Sources > BigQuery**.
2. Pick a new **Data Sync Frequency**. The button changes from Disconnect to **Update**.
3. Select **Update**.

Nothing else is editable while connected. To change the dataset or the account type, disconnect and connect again.

## Disconnect

1. Open **Settings > Data Sources > BigQuery** and select **Disconnect**.
2. Confirm in the dialog.
   ![A confirmation dialog asks whether to disconnect the BigQuery account, with Cancel and Disconnect buttons.](https://cdn.sanity.io/images/lnrtvsvr/development/85f354214ba3bdbb34546f10bad12751aa03e1d4-1650x747.jpg)
   *Step 2: Disconnecting stops the schedule. It leaves the table and its rows in your dataset.*

Brand Control Center drops its stored credentials and schedule. The `genuin_data` table and every row already written stay in your dataset. You can reconnect at any time. Reconnecting to the same dataset reuses the existing table, so history and new rows stay together.

## Limits

| Item | Limit |
| --- | --- |
| Datasets per brand | One |
| Table name | genuin_data, fixed |
| Columns | 145, all nullable, managed by Genuin |
| Sync frequency | Daily, Weekly, or Monthly |
| Key file | Service account JSON, under 10 KB |
| Dataset ID | project_id.dataset_name, letters, digits, hyphens, underscores |

## Limitations

- **Batch delivery only.** Rows arrive on the chosen schedule, not as events happen.
- **One dataset and one table.** The brand connects a single dataset, and all events share `genuin_data`.
- **Schema is fixed.** New columns arrive with product releases. Build queries that tolerate added columns.
- **Dataset and account type lock on connect.** Changing either means disconnect and reconnect.

## See also

- [Query Genuin event data in BigQuery](https://begenuin.com/developers/developer-resources/api/integrate-google-bigquery-with-brand-control-center)
- [Push analytics data to Mixpanel](https://begenuin.com/developers/developer-resources/api/integrate-mixpanel-with-brand-control-center)
- [Push analytics data to Amazon S3](https://begenuin.com/developers/developer-resources/api/how-do-i-integrate-amazon-s3-bucket-with-brand-control-center-to-push-analytics-data)
- [How zero-party data powers your social experience and media revenue](https://begenuin.com/developers/browse-by-products/control/how-zero-party-data-powers-brand-communities-and-media-revenue-without-compromising-consumer-trust)
- [How privacy and consent work with zero-party data](https://begenuin.com/developers/browse-by-products/control/how-does-genuin-ensure-privacy-and-consent-with-zero-party-data)
