Feed format
Parquet
Apache Parquet feed
Parquet is a binary columnar format with a declared schema, which makes it the most compact and the most strictly typed way to submit a product feed. OpenAI prefers it, and it is the only format documented here where the field types are part of the file rather than a convention.
Specification
- File extension
-
.parquet - Content type
- application/vnd.apache.parquet
- Compression
- Compression is internal to the format. Zstd is the preferred codec for an OpenAI feed, and there is no separate gzip step.
- One product is
- A binary file holding a schema and then the data stored column by column rather than row by row. One product is a row in the logical sense, but its values are physically grouped with the same field from every other product, which is what makes it compress so well.
- Escaping
- There is no escaping, because the format is not text: a comma, a quote or a newline inside a description is simply part of a value. What replaces escaping is type discipline, and the rule that matters is declaring identifiers as strings rather than integers so leading zeros survive.
A valid apache parquet feed
Two products, every required attribute, nothing omitted for brevity. Copy it and replace the values.
# Parquet is a binary columnar format, so what matters is the schema rather than the bytes.
# The same two products as the other examples on this site, as a Parquet schema:
message product {
required binary item_id (STRING);
required binary title (STRING);
required binary description (STRING);
required binary url (STRING);
required binary image_url (STRING);
required binary availability (STRING);
required binary price (STRING); # "49.00 GBP" — amount and ISO code in one value
required binary brand (STRING);
required binary seller_name (STRING);
optional binary gtin (STRING); # string, not integer: leading zeros are significant
optional binary group_id (STRING);
optional boolean listing_has_variations;
optional group variant_dict (MAP) {
repeated group key_value {
required binary key (STRING);
required binary value (STRING);
}
}
}
Which channels accept it
| Channel | Support | Notes |
|---|---|---|
| OpenAI | Preferred | The preferred format, with zstd compression. |
| Google Shopping | Not supported | Google takes text or XML files. |
| Meta | Not supported | Meta takes CSV, TSV, XML or Google Sheets. |
| Microsoft Advertising | Not supported | Microsoft takes tab-delimited text or XML. |
| Not supported | Pinterest takes CSV, TSV or XML. |
What breaks a apache parquet feed
Typing an identifier as a number destroys it
Parquet will happily store a GTIN as an int64, and a twelve-digit UPC beginning with zero loses that zero permanently. Unlike a text format, there is no way to tell afterwards that it was ever there. Every identifier belongs in a string column.
You cannot inspect it with an editor
A broken CSV can be opened and read. A Parquet file requires tooling, which means a validation step in your own pipeline is not optional: whatever you cannot see, you have to check programmatically before it is pushed.
The schema has to stay stable
Because the types are declared in the file, a generator that infers them from the data can produce a different schema when the data changes, for instance typing a column as integer on the day every value happens to be numeric. Declare the schema explicitly rather than letting a library guess it per run.
It is the right choice only at scale
Parquet earns its complexity on a large catalogue, where the compression and the typing both pay off. For a few thousand products, gzipped TSV or JSONL is easier to build, easier to debug and accepted by the same channel.
Frequently asked questions
Why does OpenAI prefer Parquet for a product feed?
Because it is columnar and typed: a large catalogue compresses far smaller than the equivalent text file, and the field types are declared in the file rather than inferred from the values.
How should GTINs be typed in a Parquet feed?
As strings, always. An integer column silently discards leading zeros, and because the format is binary there is no way to notice afterwards.
Do I need Parquet, or will gzipped TSV do?
Gzipped TSV is accepted and is much easier to produce and debug. Parquet is worth the extra work on a large catalogue, where the size and typing benefits are real.
What compression does a Parquet feed use?
Compression is built into the format, with zstd preferred for an OpenAI feed. There is no separate gzip step, and adding one is not expected.
Errors this format causes
Related concepts
Primary sources
Channel specifications change. These are the official documents this page is based on.