AI Studio Exporter

#Data reference

Field-level documentation for the machine-readable formats. If you are writing code against an export, this is the page you want.


#JSON

schemaVersion is 1. A breaking change to any field below bumps it; adding an optional field does not.

Fields marked optional are omitted entirely, not set to null, when the setting that controls them is off. Read them with a default. The distinction is deliberate: undefined means "not exported", null means "AI Studio had no value".

#Top level

Field Type Notes
schemaVersion number Currently 1.
exporter string Always "ai-studio-exporter". Use it to recognise the file.
id string The AI Studio prompt id (a bare Drive id, no prompts/ prefix).
title string Conversation title. "Untitled Conversation" when AI Studio has none.
url string or optional Canonical AI Studio URL. Omitted unless includeSourceUrl.
source "api" or "dom" Which extractor produced this. See source.
exportedAt ISO 8601 string When the export ran.
modifiedAt ISO 8601 string or null Last modification per AI Studio. null if unknown.
config object or null or optional Model settings. Omitted unless includeModelConfig.
systemInstruction string or null or optional Omitted unless includeSystemInstruction.
stats object See stats.
turns array The conversation. See turns.

#config

null when AI Studio reported no configuration; individual fields are null when that one value was absent.

Field Type Notes
model string or null Prefixed, e.g. "models/gemini-3-pro". Human-facing formats strip models/.
temperature number or null
topP number or null
topK number or null
maxOutputTokens number or null
safetySettings array [{category: number, threshold: number}], AI Studio's own numeric enums, passed through unmapped.

#stats

Recomputed after settings are applied, so it describes what is in the file, not what the conversation originally held. Exclude reasoning and thoughtTurns is 0.

Field Type Notes
turnCount number Total turns in this export.
userTurns number
modelTurns number Answers only; excludes reasoning.
thoughtTurns number Reasoning turns.
totalTokens number or null Sum of per-turn counts. null if AI Studio reported none.
attachments number Attachments actually present in the export.

#turns

Field Type Notes
role "user" or "model"
isThought boolean true marks reasoning. Always a model turn.
text string Message body, as Markdown. May be "" on an attachment-only turn.
tokenCount number or null or optional Omitted unless includeTokenCounts.
excludedAttachments number or optional See below. Omitted when 0.
timestamp ISO 8601 string or optional Omitted unless includeTimestamps, or when AI Studio reported none.
parts array or optional Attachments. Omitted when the turn has none.

#parts[]

Field Type Notes
type "image" or "file" Decided by MIME type, not by extension.
name string or undefined Original filename, when AI Studio knew one.
mimeType string or undefined As reported by Drive.
driveId string or undefined Drive resource id. Stable; useful for deduplicating across exports.
byteLength number or undefined Size of the retrieved file.
path string or null Path inside the archive, e.g. "attachments/screenshot.png". null means the bytes could not be fetched (the record of the attachment is kept, but no file exists).

#excludedAttachments

The number of attachments this turn had that are not in the export, because scrapeImages or scrapeAttachments excluded them.

It exists because removing them outright left messages that were nothing but a heading and a token count, which reads as a bug. If you are treating an export as a dataset, check this field: a turn with excludedAttachments > 0 is incomplete, and you cannot tell that from parts alone.


#JSONL

One JSON object per line. No wrapper array, no trailing comma, \n-terminated.

{"messages": [{"role": "system", "content": "…"}, {"role": "user", "content": "…"}, {"role": "assistant", "content": "…"}]}
Field Notes
messages[].role "system", "user" or "assistant". The model's "model" role is renamed to "assistant" to match the fine-tuning convention.
messages[].content String. Attachments appear as a leading [attachment: name] line, then a blank line, then the message text.

system appears only if the conversation had a system instruction. Note that it is included whenever one exists; the includeSystemInstruction setting strips it upstream, so turning that off removes it here too.

Line-count caveat: the number of lines is not the number of conversations you selected. A conversation with no assistant reply produces no line at all. The export's own summary reports what actually landed in the file.

#jsonlIncludeReasoning

Off by default. When off, reasoning turns are skipped entirely. When on, each becomes an assistant message and (because it is adjacent to the real answer, which is also assistant) is merged into it with a blank line between.


#CSV

One row per turn. UTF-8 with a BOM, CRLF line endings, every field quoted.

Column Notes
conversation_id AI Studio prompt id. Repeated on every row of the conversation.
conversation_title Repeated on every row.
turn_index 0-based, within this conversation. In a combined library export, indices restart per conversation; group by conversation_id before ordering.
role user or model.
is_reasoning true or false as literal text.
timestamp ISO 8601, or empty if unavailable or includeTimestamps is off.
token_count Integer, or empty.
attachments Filenames joined by "; ". Empty when there are none. Falls back to the Drive id, then to attachment, when the name is unknown.
text The full message body, newlines and all, inside the quoted field.

Formula-injection guard: any cell whose text begins =, +, -, @, tab or CR is prefixed with a single apostrophe. Strip a leading ' if you are parsing programmatically and the original value matters.


#Library manifest

A whole-library export to a per-conversation format writes two extra files at the root of each archive.

index.md is a human-readable listing linking to every conversation, plus any failures.

manifest.json:

{
  "exporter": "ai-studio-exporter",
  "exportedAt": "2026-07-31T06:40:38.000Z",
  "format": "markdown",
  "volume": 1,
  "volumeCount": 2,
  "library": [
    {
      "title": "How does the RPC auth work?",
      "path": "how-does-the-rpc-auth-work/conversation.md",
      "modifiedAt": 1750000000000,
      "turnCount": 5,
      "volume": 1
    },
    {
      "title": "Design Review",
      "path": "design-review/conversation.md",
      "modifiedAt": 1749000000000,
      "turnCount": 210,
      "volume": 2
    }
  ],
  "conversations": [
    {
      "title": "How does the RPC auth work?",
      "path": "how-does-the-rpc-auth-work/conversation.md",
      "modifiedAt": 1750000000000,
      "turnCount": 5,
      "volume": 1
    }
  ],
  "failures": []
}
Field Notes
format The format id, matching the ids in format guide.
volume / volumeCount Archives are split near 256 MB. See what you download.
library Every conversation in the export, wherever it ended up. Present even when there is only one archive, so a consumer never has to special-case that.
conversations Only what this archive holds. path resolves inside it; a path from library may not.
*.volume Which part holds that conversation (always 1 when the export was not split).
*.modifiedAt Epoch milliseconds here, not ISO (this file is written by the batch layer, not the JSON formatter).
failures [{id, title, error}]. Repeated in every part: a failure list that exists in one archive out of three is one most people never see.

#Value glossary

#source

"api" is read from AI Studio's own backend. Full fidelity: token counts, timestamps, model configuration, system instruction, and attachment bytes.

"dom" is scraped from the rendered page, used when the API path is unavailable. Only what the page displays: no token counts, no model config, no system instruction, and attachments limited to what was rendered. If fields are missing across the board, check this first.

#isThought

Marks a model turn as reasoning rather than the answer. Reasoning is a sibling of the answer in the turn list, not a child of it, because that is how AI Studio stores it. A question typically produces two model turns in sequence, the first with isThought: true.

#Token counts

AI Studio's own numbers, passed through unmodified; they are not a re-count, and not comparable to a tokenizer you run yourself. A turn with no reported count is null, never 0.

When condenseAttachments folds attachment turns into a message, their token counts are summed into the surviving turn, so a conversation's total is unchanged by the setting.

#Attachment type

image or file, decided from the MIME type rather than the extension. This is what scrapeImages and scrapeAttachments filter on, and what decides whether Markdown and HTML embed the file inline or link to it.