> For the complete documentation index, see [llms.txt](https://docs.cogram.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cogram.com/administration/data-export-package-layout.md).

# Data Export Package Layout

A Cogram [Data Export](/administration/data-exports.md) is delivered as one or more zip files. This page documents what's inside them, so you know exactly where to find every kind of data after unpacking.

The layout is **stable and self-describing**: every entity has a predictable folder, every binary lives next to its metadata, and customer-uploaded filenames are preserved (sanitized for filesystem safety). If you script downstream processing of the package, you can rely on the paths below.

## Multi-part zips

Large exports are split into multiple parts so each zip stays a manageable size. Each part is delivered with a filename like:

```
Cogram_data_export_<YYYY-MM-DD_HH-MM-SS>_part_NNN_<scope>_<window>.zip
```

* `<YYYY-MM-DD_HH-MM-SS>`: when the export was requested (UTC). Different invocations of the same scope/window never overwrite each other on disk.
* `NNN`: zero-padded part index (`000`, `001`, …) so parts sort in build order.
* `<scope>`: `all_projects` for org-wide exports, your project's `customer_project_id` (falling back to the sanitized project name) for a single-project export, or `<N>_projects` when the export covers several projects.
* `<window>`: `all_time` or `YYYY-MM-DD_to_YYYY-MM-DD`.

To reconstruct the full package, **unzip every part into the same directory**. The folder structure below is shared across parts; extracting all of them merges into one coherent tree. No single entity is split across parts.

## Top-level structure

After unzipping every part into the same folder, you get:

```
projects/
workflows/               ← only present if there are workflows in scope
```

* **`projects/`**: every entity lives under here, grouped by project. Every meeting belongs to a project; a meeting that isn't filed into a shared team project lives under its owner's personal **"My Workspace"** project folder (identifiable by `is_personal: true` in that project's `project.json`).
* **`workflows/`**: workflows sit at the root, not under any single project, because a workflow can target multiple projects. Each `workflow.json` carries a `project_ids[]` field to cross-reference back.

## Per-project folder

Each project gets its own folder under `projects/`, named:

```
projects/<prj_KSUID>__<sanitized_name>__<sanitized_customer_project_id>/
```

For example:

```
projects/prj_2abc123…__Skyrise-Tower-Phase-2__SRT-002/
```

* The **leading KSUID** is the project's unique Cogram ID: your stable identifier for joining back to the API.
* The **sanitized name** and **customer project ID** are included purely for human navigation. The `customer_project_id` is *not* unique inside an org (it's a label, not an identifier), so always disambiguate via the KSUID.
* The `__` (double underscore) separator visually marks the boundary between the KSUID and the human-readable suffix.

Inside each project folder, you'll find one subfolder per entity type that has any data in scope (subfolders are omitted when empty):

```
projects/<prj-folder>/
├── project.json
├── meetings/
├── emails/
├── documents/
├── drawings/
├── drawing_sets/
├── reports/
├── observations/
├── transmittals/
├── submittals/
└── rfis/
```

`project.json` holds the project's metadata (name, address, members, custom fields, etc.).

## Per-entity layout

With one exception (emails), every entity gets its own folder, named:

```
<KSUID>__<sanitized_truncated_name>/
```

Inside that folder are the entity's JSON metadata file and an optional `attachments/` subfolder for binaries:

```
projects/<prj-folder>/<entity-type>/<KSUID>__<name>/
├── <entity>.json
└── attachments/
    └── …binaries…
```

`KSUID` stable IDs let you join entities back to the API or to each other (e.g. a meeting referenced from a transmittal). The trailing name suffix is truncated to \~20 characters and sanitized: slashes, NULs, and other unsafe characters are collapsed to dashes, so a customer-uploaded title can never escape its folder.

### Meetings

```
meetings/<mtg_KSUID>__<title>/
├── meeting.json            ← metadata only (no transcript)
├── transcript.json         ← only when transcripts are enabled AND present
├── meeting.md              ← always written, human-readable rendering
├── meeting.docx            ← rendered via your org's default template, if any
└── attachments/
    ├── attachment-001-<original-filename>
    ├── attachment-002-<original-filename>
    ├── photo-001.jpg
    └── photo-002.jpg
```

* **`meeting.docx`** uses your organization's default `.docx` template (see [Setting a meeting template before exporting](/administration/data-exports.md#choosing-a-meeting-template-before-exporting)). It's best-effort: when no template is configured or a single render fails, the `.docx` is skipped and the build keeps going. The `.json` and `.md` siblings are always written.
* **`transcript.json`** is a sibling of `meeting.json` rather than a section inside it, so a directory listing immediately answers "is there a transcript?" with no JSON parsing required.
* **`attachments/`** holds uploaded meeting attachments and in-meeting photos only. Attachments and photos are indexed (`attachment-001-…`, `photo-001.jpg`) so two files with the same original name never collide.
* **Audio recordings are not exported.** Meeting audio stays inside Cogram by policy; the exported transcript, `meeting.md`, and `meeting.docx` are the user-facing meeting payload.

A meeting that isn't filed into a shared project lives under its owner's personal **"My Workspace"** project folder (`projects/<workspace-folder>/meetings/…`), the same internal layout as any other meeting.

### Emails: flat `.eml` files

Emails are the **one exception** to the per-entity-folder rule. They ship as flat RFC-822 `.eml` files inside `emails/`, with **attachments embedded inline** in the message body:

```
emails/<YYYY-MM-DD>_<HHMMSS>_<safe-subject>_<email_KSUID>.eml
```

Each `.eml` opens in any standard mail client (Outlook, Apple Mail, Thunderbird) with all original headers, body, and attachments intact. The filename leads with the date+time so a directory listing sorts chronologically.

There is **no JSON sidecar** for emails: the `.eml` is the complete record. (This mirrors how email is universally archived elsewhere.)

### Documents

```
documents/<doc_KSUID>__<title>/
├── document.json
└── attachments/
    └── <original-filename>    ← the document binary itself
```

The single binary under `attachments/` keeps its original filename (sanitized).

### Drawings

```
drawings/<drw_KSUID>__<title>/
├── drawing.json
└── attachments/
    ├── revision-001.pdf
    ├── revision-002.pdf
    └── revision-003.pdf
```

One file per revision, numbered so revisions sort and are unambiguous. Cogram prefers the original PDF when available, falling back to a rendered image for legacy revisions. **Thumbnails are not exported**: they're a UI optimization, not customer data.

A separate `drawing_sets/` folder lists Cogram's customer-defined drawing groupings:

```
drawing_sets/<set_KSUID>__<name>/
└── drawing_set.json
```

### Reports

```
reports/<rpt_KSUID>__<title>/
└── report.json
```

Reports have no binary attachments: the JSON is the whole record. Custom field values are inlined into `report.json` rather than living in a sibling folder.

### Observations

```
observations/<obs_KSUID>__<title>/
├── observation.json
└── attachments/
    ├── photo-001.jpg
    ├── photo-002.jpg
    └── …
```

Photos are exported at full resolution. Indexed filenames (`photo-001.jpg`, `photo-002.jpg`, …) avoid collisions with camera-default filenames.

### Transmittals

```
transmittals/<tmt_KSUID>__<subject>/
└── transmittal.json
```

Transmittals reference documents by their KSUID. The actual document binaries live under `projects/<prj-folder>/documents/`; no copies are made.

### Submittals and RFIs (Procore-synced)

When your project is connected to Procore, submittals and RFIs are included with both Cogram's wrapper metadata (workflow status, AI checks, response state) and the verbatim Procore raw object:

```
submittals/<sub_KSUID>/
├── submittal.json
└── attachments/
    ├── submittal-attachment-001-<filename>
    ├── approver-<approver_KSUID>-attachment-001-<filename>
    └── external-review-<inv_KSUID>-attachment-001-<filename>

rfis/<rfi_KSUID>/
├── rfi.json
└── attachments/
    ├── question-<q_KSUID>-attachment-001-<filename>
    ├── answer-<a_KSUID>-attachment-001-<filename>
    └── external-review-<inv_KSUID>-attachment-001-<filename>
```

The filename prefix (`submittal-`, `approver-`, `question-`, `answer-`, `external-review-`) tells you exactly which part of the submittal or RFI lifecycle each binary belongs to. The owning parent's KSUID is embedded in the filename for full traceability.

Cogram only ships attachment binaries that it actually downloaded from Procore. If a Procore-only attachment was never mirrored locally, its metadata still appears in the parent JSON but no binary file is written.

### Workflows

```
workflows/<wf_KSUID>__<name>/
└── workflow.json
```

Workflows sit at the root because a workflow targets one or more projects via `project_ids[]`. Workflow runs are inlined into `workflow.json` rather than written as sibling files.

## Identifying example / demo data

Every new Cogram organization is seeded with an **example project**, *"Example Project: Skyrise Tower"*, plus sample meetings, emails, drawings, reports, and observations, so you can explore the product before your real data lands. This example data **is included in exports**. To tell it apart from your real data (and filter it out), use the `is_dummy` flag:

* **JSON entities** carry an **`is_dummy`** boolean: `true` means Cogram-generated example data, `false` means your own data. It's present in `project.json`, `meeting.json`, `drawing.json`, `report.json`, and `observation.json`.
* **`project.json`** additionally carries **`is_personal`**: `true` for a personal workspace (e.g. your default *"My Workspace"*) as opposed to a shared team project. This is independent of `is_dummy`: a personal project can be real (`is_dummy: false`).
* **Emails** have no JSON sidecar, so the same signal rides as an RFC-822 header: every `.eml` carries **`X-Cogram-Is-Dummy: true`** or **`false`** (alongside other `X-Cogram-*` metadata headers such as `X-Cogram-Email-Id`).

To exclude all example data in one pass, drop any entity where `is_dummy` is `true` (or, for emails, where `X-Cogram-Is-Dummy` is `true`). Because example data is grouped under the example project's folder, you can also skip that project's folder wholesale, but the per-entity flag is the reliable signal.

## Filename and path safety

Cogram aggressively sanitizes customer-uploaded names before they become parts of a path:

* Anything outside `[A-Za-z0-9._-]` is collapsed to a single dash.
* Leading and trailing dots/dashes are stripped (so `../foo` and `..` can never reach a parent directory).
* The human-readable suffix on each entity folder is truncated to \~20 characters (30 for project names) so deeply nested paths stay under typical filesystem limits when extracted.

The stable **KSUID** at the start of each entity folder is the part you should rely on programmatically; the sanitized name suffix is purely for human navigation.

## Putting it together

A complete export of a single project named "Skyrise Tower" with one meeting and one drawing might look like:

```
Cogram_data_export_2026-05-20_14-32-15_part_000_SRT-002_2026-01-01_to_2026-05-20.zip
└── projects/prj_2abc…__Skyrise-Tower__SRT-002/
    ├── project.json
    ├── meetings/mtg_3def…__Weekly-OAC-2026-/
    │   ├── meeting.json
    │   ├── transcript.json
    │   ├── meeting.md
    │   ├── meeting.docx
    │   └── attachments/
    │       ├── attachment-001-agenda.pdf
    │       └── photo-001.jpg
    └── drawings/drw_4ghi…__A-101-Floor-Plan/
        ├── drawing.json
        └── attachments/
            ├── revision-001.pdf
            └── revision-002.pdf
```

Every path is deterministic from the entity's type and KSUID, so once you've unpacked a few exports the layout becomes second nature, and trivial to drive from a script.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.cogram.com/administration/data-export-package-layout.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
