In this quickstart, you obtain an OAuth token for your account, and you send requests to the Data Portability API endpoints using timestamps to filter the exported data.
This quickstart covers how to use the Data Portability API with time-based access and apply time filters for supported resources. For more details on time-based access to user data, see Use Time-Based Access.
What you learn
In this quickstart you learn how to:
- Send recurring authenticated requests to the
InitiatePortabilityArchive
endpoint to only export new data since your last export. - Send an authenticated request to the
InitiatePortabilityArchive
endpoint to only export data from the last 6 months. - Send an authenticated request to the
InitiatePortabilityArchive
endpoint to only export data from a specific time period.
Prerequisites
To run this quickstart, you need to:
- Verify that the Data Portability API is available to users in your location. For a list of supported countries and regions, see Common Questions on the "Share a copy of your data with a third party" page.
- Complete the setup steps for the Data Portability API.
- Follow the steps to configure OAuth for
JavaScript web apps. In production, you would
normally use a different flow like the OAuth flow for
web server applications.
For simplicity, this quickstart uses the JavaScript web app flow.
- When you create your authorization credentials, make a note of your OAuth 2.0 Client ID and your authorized redirect URI (for example, https://google.com). You need them later in the quickstart.
- When you configure scopes for the Data Portability API, note
that this quickstart uses the
myactivity.search
resource group: https://www.googleapis.com/auth/dataportability.myactivity.search. - When you choose the amount of time you want to allow access, you should select 30 days to test time filtering with time-based access. (Time Filters also work with one-time access).
- Obtain an OAuth token.
- Obtain access to an account owned or controlled by your organization. This account's search activity data is exported in this quickstart.
Obtain an OAuth token
For this quickstart, you send an authorization request to obtain an OAuth token using a URL. This process uses the flow for JavaScript web apps. This flow does not return a refresh token.
For a production app, you would typically use an OAuth flow to obtain a refresh token that can be used to generate access tokens on demand. An example of this would be the flow for server-side web apps.
To obtain an OAuth token:
Compose a URL like the following.
https://accounts.google.com/o/oauth2/v2/auth? client_id=client_id& redirect_uri=redirect_uri& response_type=token& scope=https://www.googleapis.com/auth/dataportability.myactivity.search& state=developer-specified-value
In the URL:
client_id
is your OAuth client ID.redirect_uri
is your authorized redirect URI; for example, https://google.com.
Notice that the scope used in the URL for this quickstart is the search activity scope. You can use any scopes that support Time Filters.
Paste the URL into your browser's address bar, and follow the steps in the OAuth flow. This flow requires you to sign into the account owned or controlled by your organization that you're using for this quickstart.
This is the account that's consenting to the OAuth scopes. The consent screen should look like this (the text in your screen may vary from the text in this image):
Choose the scopes to grant access to and the length of time to share access to the account's data (once, 30 days, or 180 days). For this quickstart, choose 30 days. (Time Filters also work with one-time access.)
After granting consent and deciding the duration of access, you should be forwarded to the redirect URI—https://google.com. The URL that is generated in the address bar includes the OAuth access token.
For example, if the user account grants OAuth access to the
dataportability.myactivity.search
scope, the generated URL looks like this:https://google.com/#state=developer-specified-value&access_token=your_OAuth_token&token_type=Bearer&expires_in=3599&scope=https://www.googleapis.com/auth/dataportability.myactivity.search
In the URL, your_OAuth_token is a string that represents the token.
To validate the OAuth token, paste this URL into your browser:
https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=your_OAuth_token
The response should look like this:
{ "azp": <your_azp_value>, "aud": <your_aud_value>, "scope": "https://www.googleapis.com/auth/dataportability.myactivity.search", "exp": "1694210968", "expires_in": "3334", "access_type": "online" }
You don't need the
azp
oraud
fields to make requests. Theazp
field represents theclient_id
of the authorized presenter, and theaud
field identifies the audience that this token is intended for, which will be equal to one of the client IDs for your application.Gather your OAuth token and your API key. You need these to make calls to the Data Portability API.
Send requests to the endpoints
In this quickstart you use curl commands to call the Data Portability API endpoints with timestamps to filter the exported data.These commands require the OAuth token and API key you gathered previously.
Data from last export
You can use Time Filters with Time-Based Access to export the
new data since your last export. For example, consider the scope
https://www.googleapis.com/auth/dataportability.myactivity.search
.
First, you send an authenticated request to the
InitiatePortabilityArchive
endpoint. This request starts an archive job for the full data corpus.Run the following curl command:
curl -H 'Authorization: Bearer your_OAuth_token' -X POST \ -H "Content-Type: application/json; charset=utf-8" \ --data '{"resources":["myactivity.search"]}' \ https://dataportability.googleapis.com/v1/portabilityArchive:initiate
In the command:
your_OAuth_token
is your OAuth token.
The
InitiatePortabilityArchive
request returns anarchiveJobId
andaccessType
. The job ID is used to retrieve the state of the data archive and the access type determines if you have been granted one-time or time-based access to the data. For time-based access, you'll see:{ "archiveJobId": "<your_job_id_1>" "accessType": "ACCESS_TYPE_TIME_BASED" }
If you fail to provide a valid OAuth token, this error message is returned:
Request had invalid authentication credentials. Expected OAuth 2.0 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
Next, you send an authenticated request to the
GetPortabilityArchiveState
endpoint to retrieve the status of the archive job.Run the following curl command:
curl -H 'Authorization: Bearer your_OAuth_token' -X GET \ -H "Content-Type: application/json; charset=utf-8" \ https://dataportability.googleapis.com/v1/archiveJobs/your_job_id_1/portabilityArchiveState
In the command:
your_OAuth_token
is your OAuth token.your_job_id_1
is the job ID returned by theInitiatePortabilityArchive
request.
The response is based on the state of the job. If the job is not complete, the response provides the current state. You should send requests to this endpoint periodically until the job is complete.
{ "state": "IN_PROGRESS" }
If the job is complete, the response contains the state and one or more signed URLs that are used to download the data archive. There is also an
export_time
field that represents the timestamp when the first call toInitiatePortabilityArchive
was made.{ "state": "COMPLETE", "urls": [ "<signed_url>" ] "export_time": "<timestamp_of_first_initiate_request>" }
Paste the signed URL into your browser to download the data archive. You should examine the contents of the archive to ensure that it contains the expected search activity data.
If you receive a
FAILED
state in the response, you may retry the export using theRetryPortabilityArchive
method.Wait at least 24 hours and then make another request to
InitiatePortabilityArchive
using the same command as in step 1, but this time use theexport_time
as thestart_time
.curl -H 'Authorization: Bearer your_OAuth_token' -X POST \ -H "Content-Type: application/json; charset=utf-8" \ --data '{"resources":["myactivity.search"], "start_time": timestamp_of_first_initiate_request}' \ https://dataportability.googleapis.com/v1/portabilityArchive:initiate
For time-based access, this will return:
{ "archiveJobId": "<your_job_id_2>" "accessType": "ACCESS_TYPE_TIME_BASED" }
Repeat step 2 to send an authenticated request to the
GetPortabilityArchiveState
endpoint to retrieve the status of the archive job (using<your_job_id_2>
).When the job is complete, the response will be:
{ "state": "COMPLETE", "urls": [ "signed_urls" ], "start_time": timestamp_of_first_initiate_request, "export_time": timestamp_of_second_initiate_request }
Verify that the data in the second export only contains new data generated after the first export.
Data from last 6 months
You can also use Time Filters to export only the most recent data instead of the full corpus.
Assume today's date is
2024-10-01
and you want to export the last 6 months of data. First, you send an authenticated request to theInitiatePortabilityArchive
endpoint with astart_time
of "2024-04-01T00:00:00Z".Run the following curl command:
curl -H 'Authorization: Bearer your_OAuth_token' -X POST \ -H "Content-Type: application/json; charset=utf-8" \ --data '{"resources":["myactivity.search"], "start_time": "2024-04-01T00:00:00Z"}' \ https://dataportability.googleapis.com/v1/portabilityArchive:initiate
For time-based access, this will return:
{ "archiveJobId": "job_id_1" "accessType": "ACCESS_TYPE_TIME_BASED" }
Make a request to the
GetPortabilityArchiveState
endpoint to retrieve the status of the archive job.Run the following curl command:
curl -H 'Authorization: Bearer your_OAuth_token' -X GET \ -H "Content-Type: application/json; charset=utf-8" \ https://dataportability.googleapis.com/v1/archiveJobs/job_id_1/portabilityArchiveState
When the job is complete, the response will be:
{ "state": "COMPLETE", "urls": [ "signed_urls" ], "start_time": "2024-04-01T00:00:00Z", "export_time": "2024-10-01T00:00:00Z" }
Note that the
start_time
is thestart_time
specified in step 1 and theexport_time
is the timestamp when the call toInitiatePortabilityArchive
was made in step 1.Verify that the export only contains data from the last six months.
Data from a specific time period
You can use Time Filters to export data from a specific range of dates, such as data from 2023 only.
First, you send an authenticated request to the
InitiatePortabilityArchive
endpoint with astart_time
of "2023-01-01T00:00:00Z" and anend_time
of "2023-12-31T23:59:59Z".Run the following curl command:
curl -H 'Authorization: Bearer your_OAuth_token' -X POST \ -H "Content-Type: application/json; charset=utf-8" \ --data '{"resources":["myactivity.search"], "start_time": "2023-01-01T00:00:00Z", "end_time": "2023-12-31T23:59:59Z"}' \ https://dataportability.googleapis.com/v1/portabilityArchive:initiate
For time-based access, this will return:
{ "archiveJobId": "job_id_1" "accessType": "ACCESS_TYPE_TIME_BASED" }
Make a request to the
GetPortabilityArchiveState
endpoint to retrieve the status of the archive job.Run the following curl command:
curl -H 'Authorization: Bearer your_OAuth_token' -X GET \ -H "Content-Type: application/json; charset=utf-8" \ https://dataportability.googleapis.com/v1/archiveJobs/job_id_1/portabilityArchiveState
When the job is complete, the response will be:
{ "state": "COMPLETE", "urls": [ "signed_urls" ], "start_time": "2023-01-01T00:00:00Z", "export_time": "2023-12-31T23:59:59Z" }
Note that the
start_time
is thestart_time
specified in step 1 and theexport_time
is equal to theend_time
provided in step 1.Verify that the export only contains data from 2023.
Supported scopes
The following scopes support Time Filters:
https://www.googleapis.com/auth/dataportability.myactivity.youtube
https://www.googleapis.com/auth/dataportability.myactivity.maps
https://www.googleapis.com/auth/dataportability.myactivity.search
https://www.googleapis.com/auth/dataportability.myactivity.myadcenter
https://www.googleapis.com/auth/dataportability.myactivity.shopping
https://www.googleapis.com/auth/dataportability.myactivity.play
https://www.googleapis.com/auth/dataportability.chrome.history
Caution: Time-filtered requests that mix supported and unsupported
scopes result in an INVALID_ARGUMENT
error that states The requested
resources do not support time filters
.