> For the complete documentation index, see [llms.txt](https://docs.chord.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.chord.co/connect-sources/data-sources/connect-data-sources/ga4-via-bigquery.md).

# GA4 via BigQuery

Chord uses a service account in your Google Cloud project to copy your GA4 export out of BigQuery and into your Cloud Storage bucket.

You create the account, grant it four roles, and send Chord the account details and a JSON key.

Before you start, you need an active [GA4 to BigQuery link](https://support.google.com/analytics/answer/9823238) and a landing bucket that [Chord can read](/connect-sources/sharing-data-with-chord-from-cloud-storage.md#configuring-an-integration-for-google-cloud-storag).

{% hint style="info" %}
Pick one way to set this up, not both.

**Option A** uses the Google Cloud console.

**Option B** runs the same steps with the gcloud CLI.

Both end in the same place. Then go to [What to send Chord](#what-to-send-chord).
{% endhint %}

## Option A: Google Cloud console

### Create the service account

Use the project that holds your `analytics_<property_id>` dataset.

1. In the Google Cloud console, open the **Create service account** page and select that project.
2. Enter a name, for example `chord-ga4`. Google builds the account ID from it, and you cannot change the ID later.
3. Click **Create and continue**, then\*\* Done\*\*. You will grant the roles in the next section, so you can skip the role step here.

{% hint style="info" %}
You need the Create Service Accounts role (`roles/iam.serviceAccountCreator`) on the project. To grant roles you also need Project IAM Admin (`roles/resourcemanager.projectIamAdmin`). A new service account can take a minute or more before it is usable.
{% endhint %}

### Grant the roles

Grant each role at the narrowest level Google allows. You will need the service account's email, for example `chord-ga4@your-project-id.iam.gserviceaccount.com`.

**On the project.**

BigQuery Job User and BigQuery Read Session User can only be granted on a project, folder or organization, never on a single dataset.

1. Open **IAM & Admin → IAM** and select your project.
2. Click **Grant access**.
3. Enter the service account email under **New principals**.
4. Add the roles **BigQuery Job User** and **BigQuery Read Session User**, then click\*\* Save\*\*.

**On the dataset.**

BigQuery Data Viewer only needs to cover your GA4 dataset.

1. In the Google Cloud console, open **BigQuery**.
2. In **Explorer**, expand your project, click\*\* Datasets\*\*, and select the `analytics_<property_id>` dataset.
3. Click **Sharing → Permissions**, then\*\* Add principal\*\*.
4. Enter the service account email.
5. In **Select a role**, choose\*\* BigQuery Data Viewer\*\*.
6. Click **Save**, then\*\* Close\*\*.

**On the bucket.**

Storage Object Admin only needs to cover your landing bucket.

1. Open **Cloud Storage → Buckets** and click the bucket name.
2. Open the **Permissions** tab and click **Grant access**.
3. Enter the service account email under **New principals**.
4. In **Select a role**, choose\*\* Storage Object Admin\*\*, then click\*\* Save\*\*.

### Create a JSON key

1. Open the **Service accounts** page and select your project.
2. Click the email address of the service account.
3. Open the **Keys** tab.
4. Click **Add key**, then\*\* Create new key\*\*.
5. Select **JSON** as the key type and click **Create**.

The key file downloads once and Google cannot show it again.

{% hint style="danger" %}
The JSON key is a secret. Send it to Chord through a secure channel, never by email or Slack. Delete your local copy once Chord confirms the connection works.
{% endhint %}

## Option B: gcloud CLI

Skip this section if you used Option A. It does the same thing from the command line.

Set these values first.

```javascript
PROJECT_ID=your-project-id
DATASET=analytics_123456789
BUCKET=your-bucket-name
SA=chord-ga4
SA_EMAIL=$SA@$PROJECT_ID.iam.gserviceaccount.com
```

Create the account.

```javascript
gcloud iam service-accounts create $SA \
  --project=$PROJECT_ID \
  --display-name="Chord GA4 replication"
```

Grant the two project-level roles.

```javascript
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$SA_EMAIL" --role="roles/bigquery.jobUser"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$SA_EMAIL" --role="roles/bigquery.readSessionUser"
```

Grant Data Viewer on the dataset. Run this in the BigQuery query editor.

```javascript
GRANT `roles/bigquery.dataViewer`
  ON SCHEMA `your-project-id`.analytics_123456789
  TO "serviceAccount:chord-ga4@your-project-id.iam.gserviceaccount.com"
```

Grant Storage Object Admin on the bucket.

```javascript
gcloud storage buckets add-iam-policy-binding gs://$BUCKET \
  --member="serviceAccount:$SA_EMAIL" --role="roles/storage.objectAdmin"
```

Create the key.

```javascript
gcloud iam service-accounts keys create chord-ga4-key.json \
  --iam-account=$SA_EMAIL
```

The key file `chord-ga4-key.json` is saved in your current folder. Treat it as a secret, as in Option A.

## What to send Chord

1. **Service account email.** For example `chord-ga4@your-project-id.iam.gserviceaccount.com`.
2. **JSON key.** The key file, through a secure channel.
3. **GCP project ID.** The project that holds the dataset.
4. **Dataset name.** Usually `analytics_<property_id>`.
5. **Bucket name.** The full path, starting with `gs://`.

There is no setup screen in Hub for this source yet. Chord configures the connection from these values.

## Rotating and revoking access

**Rotation.** Google recommends rotating keys regularly. Create a new key, send it to Chord, wait for Chord to confirm it works, then delete the old key. Google advises disabling a key before deleting it, because a deleted key cannot be restored.

**Revoking access.** Deleting the key cuts off Chord's access, and replication stops until you send a new one. To delete a key, open the service account, open the **Keys** tab, and click **Delete** next to the key. Deleting a key does not cancel short-lived credentials already issued from it. To cut those off as well, disable or delete the service account.

## Troubleshooting

**Why can't I create the JSON key?**

Your organization may enforce the `iam.disableServiceAccountKeyCreation` policy. Google turns it on by default for organizations created on or after May 3, 2024. An organization policy administrator can exempt your project. They tag the project `not_enforced` and update the policy so it applies to everything except tagged resources. This needs the Organization Policy Administrator, Organization Viewer and Tag Administrator roles. See [Google's guide](https://docs.cloud.google.com/iam/docs/keys-create-delete).

**Why does Chord report a permission error?**

Check that all four roles are in place. The two BigQuery roles must be on the project, Data Viewer on the dataset, and Storage Object Admin on the bucket.

***

**Need help?** Contact your Chord representative or email <support@chord.co>.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.chord.co/connect-sources/data-sources/connect-data-sources/ga4-via-bigquery.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
