Skip to main content
Each hour or each UTC day, an export writes the window’s results as gzip-compressed JSON Lines to an Amazon S3 or Google Cloud Storage bucket, or loads them into a BigQuery table partition. Your warehouse reads them like any other source, with no polling loop. You grant our export identity write access to the bucket or dataset; you never share keys or passwords. Every key, bucket, account id and role on this page is a placeholder.

What is exported

Tasks submitted with any of the account’s keys, from the Playground and by monitors are all included. A window holds exactly the rows whose time falls in [windowStart, windowEnd). Delivery timing. A window is due 10 minutes after it closes, so charges settled at the boundary are in it. Due windows are picked up by a job that runs every 15 minutes, so delivery normally starts 10 to 25 minutes after the window closes.

Set up an export

1

Read your export identity

accountKey names your folder and your tables. Every path and table we write carries it, so several querying.ai accounts can share one bucket or dataset and each writes only its own files. Grant the identity your response shows, not the placeholder above.
2

Grant access

Grant the identity access to your destination. See Grant access for S3, Cloud Storage and BigQuery.
3

Create the export

POST /v1/exports checks the grant and saves the export. See Create the export.
4

Watch the first delivery

GET /v1/exports/{id}/runs lists each window and its status. See Delivery history.

Grant access

Amazon S3

Create an IAM role in your AWS account that our Google identity can assume. Use the trustPolicy from the identity response as the role’s trust policy. It accepts only our export identity, and only with your account’s session name:
Attach a permissions policy that lets the role write under your prefix:
If the bucket encrypts with a customer-managed KMS key, also allow kms:GenerateDataKey on that key.

Google Cloud Storage

Grant the export service account Storage Object User (roles/storage.objectUser) on the bucket. It creates the files and replaces them when a window is sent again.
To limit the grant to your folder, add an IAM condition on resource.name.startsWith("projects/_/buckets/acme-geo/objects/querying/acct_3f9a1c2b7d4e/").

BigQuery

Grant the export service account BigQuery Data Editor (roles/bigquery.dataEditor) on the dataset. We run the load jobs in our own project, so loading costs you nothing; you pay only for storage and the queries you run.

Create the export

Use an API key without an engine scope: an export carries every result of the account, so a key limited to some engines gets 403 KEY_SCOPE.
Before saving, the export proves the grant. For S3 and Cloud Storage it writes <prefix><accountKey>/_querying/connection-check.json; for BigQuery it reads the dataset and records its location. If the check fails, nothing is saved. An account can have up to 10 exports. The response is 201 with the export:
For S3 and Cloud Storage, destination echoes the bucket settings and adds path, the folder your files land in, such as s3://acme-geo/querying/acct_3f9a1c2b7d4e/ or gs://acme-geo/querying/acct_3f9a1c2b7d4e/. nextWindowStart is the start of the next window to be planned.

Errors

Files and tables

Files in S3 and Cloud Storage

  • Directories follow Hive partitioning (dt=, and hour= for hourly exports), so Athena, BigQuery external tables and Spark read them as columns.
  • v1 is the schema version (schemaVersion on the export). A change that breaks a column ships as v2 beside it.
  • A window splits into parts of up to 100,000 rows, in time order.
  • _manifest.json is written last. Load a window once its manifest exists, and read the part list from it:
rows in the manifest equals the number of lines in its parts and the rows of the run in the delivery history. File names depend only on the window, so a re-sent window replaces the same objects.

BigQuery tables

BigQuery exports load into querying_tasks_v1_<accountKey> and querying_monitor_results_v1_<accountKey>, created on the first load and partitioned by completedAt or ranAt (by day, or by hour for hourly exports). Each window replaces its own partition, so a re-sent window never doubles. payload, response, sources and scoringContext are JSON columns:

Row schema (v1)

tasks

monitor_results

Delivery history

Each window of each data set is one run. List them newest first:
Filter with status, data (tasks or monitor_results) and limit (1–200, default 50); pass nextCursor back as cursor for the next page.
  • Automatic retries. A failed attempt is retried after 15 minutes, then with the delay doubling up to 12 hours, eight attempts in all. error holds the storage provider’s reason, so a missing permission shows up here first.
  • Send a window again. POST /v1/exports/{id}/runs/{runId}/retry sends a window now: a failed one after you fix the grant, or a delivered one you want rewritten. It resets attempts and returns the run as pending. A run that is being delivered returns 409 EXPORT_RUN_RUNNING.
  • Export health. GET /v1/exports and GET /v1/exports/{id} add deliveredThrough (the end of the latest delivered window), failedRuns and retryingRuns (pending runs that already failed at least once).

Pause, resume and delete

  • PATCH /v1/exports/{id} with {"enabled": false} pauses an export. {"enabled": true} resumes it and catches up on the windows it missed, back to 30 days.
  • DELETE /v1/exports/{id} stops the export. Files and partitions already delivered stay in your storage.
  • Destination, interval and data sets cannot change. Create a new export and delete the old one.

Endpoints

An export you do not own returns 404 NOT_FOUND.