> ## Documentation Index
> Fetch the complete documentation index at: https://control-dev.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Parquet exports

> Deliver consolidated financial data to a warehouse as versioned Parquet snapshots.

export const ControlAppLink = ({path, breadcrumb, children}) => {
  const link = <a href={`https://app.control.dev${path}`} target="_blank" rel="noopener noreferrer" aria-label={breadcrumb ? `Open ${breadcrumb} in Control` : undefined}>
      {children}
    </a>;
  return breadcrumb ? <Tooltip tip={breadcrumb}>{link}</Tooltip> : link;
};

Parquet exports are intended for data teams that want Control's standardized financial data in a warehouse, database, or analytical workflow.

## What you receive

The Parquet catalog exposes two recommended consolidation tables and six lower-level tables for custom models. The recommended `consolidation_v1` export contains:

* `group_consolidation_gsheets`: consolidated ledger rows with mappings and currency conversion applied
* `group_consolidation_gsheets_dimensions`: aligned dimension rows for the consolidated data

Control plans the physical files adaptively: smaller ranges may be delivered as one file, while larger ranges may be split by quarter or into smaller quarter chunks.

### Table ontology

The table grain determines how rows can be joined and aggregated. Parquet preserves the BigQuery field names: modeled outputs use `snake_case`, while raw compatibility tables retain source-style names such as `accountCode` and `groupDimensionId`.

#### Recommended consolidation tables

| Table                                    | Grain                                                                                                             | Main concepts                                                                                                                     |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `group_consolidation_gsheets`            | One balance per accounting month, entity, local account, group account, and source                                | Local and group chart of accounts, income statement movement or balance sheet month-end position, local and group-currency values |
| `group_consolidation_gsheets_dimensions` | One balance per accounting month, entity, account, source dimension item, mapped group dimension item, and source | The same converted balances allocated by source and group dimensions                                                              |

Use `group_consolidation_gsheets` for account-level totals. Use `group_consolidation_gsheets_dimensions` when a report needs a dimension breakdown. The dimension table has a finer grain, so do not join it to the account-level table and then sum both tables' values.

The main field groups are:

* Time and entity: `accounting_month`, `bq_entity_id`
* Local account: `account_number`, `account_name`, `account_type`
* Group account: `group_account_number`, `group_account_name`, `group_account_type`
* Lineage: `source_system`, `source_table`
* Measures: `statement_value_local`, `statement_value_group`
* Dimension-only fields: `dimension_id`, `dimension_name`, `item_id`, `item_name`, `group_dimension_name`, `group_dimension_item_name`

#### Lower-level tables

| Table                                | Grain or key                                                                       | Purpose and important fields                                                                                                                                                 |
| ------------------------------------ | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `group_ctrl_uniform_transactions_v2` | One standardized ledger row; `composite_key` is the row key                        | Source transaction and document identifiers, local account, debit/credit/net and statement values, entity, soft-delete and freshness metadata, and nested `dimensions`       |
| `invoices_ctrl_uniform_v2`           | One normalized `record_type`, such as an invoice line, credit-note line, or charge | Document and line identifiers, dates and status, customer and product, service period, original and accounting-currency amounts, credit flag, and nested `dimensions`        |
| `ctrl_group_accounts_latest`         | One latest group account; `id` is the key                                          | Canonical group chart of accounts: `accountCode`, `name`, `description`, and `accountType`. `accountCode` corresponds to `group_account_number` in the consolidation outputs |
| `ctrl_group_dimensions_latest`       | One latest group dimension; `id` is the key                                        | Canonical dimension definitions, primarily `id` and `name`                                                                                                                   |
| `ctrl_group_dimension_items_latest`  | One latest group dimension member; `id` is the key                                 | Dimension members: `itemName`, `description`, and parent `groupDimensionId`, which joins to `ctrl_group_dimensions_latest.id`                                                |
| `fx_rates`                           | One rate per `date`, `base_currency`, and `to_currency`                            | `rate` and `forexcode`; one unit of `base_currency` equals `rate` units of `to_currency`                                                                                     |

All three `*_latest` compatibility tables also include lifecycle metadata (`createdAt`, `updatedAt`, `deletedAt`) and BigQuery ingestion metadata (`bq_ts`, `bq_batch_id`, `bq_blob_id`, `bq_entity_id`, `bq_hash`). Filter out rows with a non-null `deletedAt` when you need only active records.

Conceptually, `group_ctrl_uniform_transactions_v2` is the transaction-level fact table. Control applies account and dimension mappings plus `fx_rates` to produce the two recommended consolidation tables. `invoices_ctrl_uniform_v2` is a separate invoice-line fact table and does not join one-to-one with ledger transactions.

## Start with the recommended export

1. Open the <Tooltip tip="Data outputs → Parquet → Catalog"><ControlAppLink path="/data-outputs/parquet/catalog"><strong>Parquet catalog</strong></ControlAppLink></Tooltip>.
2. Find the recommended Consolidation export.
3. Choose the required accounting month range.
4. Request the snapshot.
5. Open <ControlAppLink path="/data-outputs/parquet/history"><strong>History</strong></ControlAppLink> and wait for the status to become **Completed**.
6. Download the generated files or automate the same flow with the API.

<Tip>
  Start with `consolidation_v1`. The raw and uniform datasets are lower-level building blocks for advanced models and
  require more knowledge of Control's internal data model.
</Tip>

## Snapshot behavior

Parquet delivery is snapshot-based, not a continuous hourly feed. A request captures a defined export and optional accounting month range. A completed snapshot remains identifiable by its snapshot ID and manifest.

For incremental loading, store each manifest entry's period or slice key and `contentHash`. On the next run, download only files whose hash changed.

## Load into a warehouse

A typical ingestion job:

1. Requests or discovers the latest completed snapshot.
2. Reads the manifest.
3. Compares period hashes with the last successful load.
4. Downloads changed files.
5. Loads each file into a staging table.
6. Replaces or merges the corresponding accounting periods atomically.
7. Records the snapshot ID and hashes as ingestion metadata.

## Example: Query a snapshot with DuckDB

After a snapshot completes, download every artifact file returned by the API into the same directory. Keep the bearer token attached to each download request.

```bash theme={null}
mkdir -p parquet-downloads

curl -L -H "Authorization: Bearer $TOKEN" \
  "<artifact-download-url>" \
  --output parquet-downloads/group_consolidation_gsheets.part-0000.parquet

duckdb ./control-parquet.duckdb
```

Create a view over all parts of the dataset and query it:

```sql theme={null}
INSTALL parquet;
LOAD parquet;

CREATE VIEW group_consolidation AS
SELECT *
FROM read_parquet('parquet-downloads/group_consolidation_gsheets*.parquet');

SELECT
  accounting_month,
  group_account_number,
  SUM(value_in_group_currency) AS amount
FROM group_consolidation
GROUP BY 1, 2
ORDER BY 1 DESC, 2
LIMIT 20;
```

Use a glob because one logical dataset can be split across several Parquet files. For recurring ingestion, download into a temporary location, validate the files, and then replace the corresponding warehouse partitions atomically.

## Access and security

API calls use a Control access-token JWT and are scoped by tenant membership. Parquet exports must also be enabled for the tenant.

Do not share download URLs or access tokens in tickets, chat, or source control. Download through the authenticated Control API.

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/product-docs/data-exports/parquet-authentication">
    Discover the authorization server and complete OAuth with PKCE.
  </Card>

  <Card title="API quickstart" icon="code" href="/product-docs/data-exports/parquet-api">
    Request a snapshot, poll status, and download changed files.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/product-docs/data-exports/parquet-webhooks">
    Receive signed consolidation-completed events.
  </Card>
</CardGroup>
