> ## Documentation Index
> Fetch the complete documentation index at: https://code.dcycle.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Files & Readings

> Upload documents, manage file readings, and create records from parsed data

<Note>
  **Early Access** - The Dcycle CLI is currently available for enterprise customers.
  [Contact us](/docs/support) to learn more about access.
</Note>

## Overview

The Files module lets you upload documents (invoices, utility bills, waste certificates), view extracted readings, correct parsed data, and create linked records — all from the terminal.

The CLI uses a **presigned upload flow** by default:

1. Request a presigned URL from `POST /v1/files/presigned-urls`
2. Upload the file directly to S3
3. Confirm the upload with `PATCH /v1/files/batch-update`

This means uploads can run autonomously from scripts and CI jobs while still triggering the normal file classification and extraction pipeline.

***

## Upload a File

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy file upload ./invoice.pdf
```

Output:

```
Uploading invoice.pdf (245.00 KB)
ID: 550e8400-e29b-41d4-a716-446655440000
Name: invoice
Extension: PDF
MIME Type: application/pdf
Size: 245 KB
Status: uploaded
Owner: Jane Doe
Created: 2024-03-15
```

### Upload Flags

| Flag           | Required | Default     | Description                                                                    |
| -------------- | -------- | ----------- | ------------------------------------------------------------------------------ |
| `--folder-id`  | No       | —           | Target folder UUID                                                             |
| `--project-id` | No       | —           | Project UUID to link after upload                                              |
| `--mode`       | No       | `presigned` | Upload mode: `presigned` (direct-to-S3) or `multipart` (legacy backend upload) |
| `--org`        | No       | —           | Organization ID override                                                       |

### Upload Examples

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Upload into a specific folder
dcy file upload ./invoice.pdf --folder-id <folder-id>

# Upload and link to a project
dcy file upload ./invoice.pdf --project-id <project-id>

# Use legacy multipart upload (for troubleshooting)
dcy file upload ./invoice.pdf --mode multipart

# JSON output for scripting
dcy file upload ./invoice.pdf --format json
```

<Tip>
  When `--project-id` is present, the CLI passes it to the batch-update step so the backend creates `file_project` associations automatically after the S3 upload succeeds.
</Tip>

***

## List Files

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy file list

# Short alias
dcy file ls
```

Output:

```
Showing 5 of 42 files
550e8400-... | invoice-march   | PDF  | 245 KB | uploaded | Jane Doe
661f9511-... | utility-bill    | PDF  | 180 KB | uploaded | John Smith
772a0622-... | waste-cert-q1   | XLSX | 95 KB  | uploaded | Jane Doe
883b1733-... | gas-invoice     | PDF  | 310 KB | uploaded | John Smith
994c2844-... | water-readings  | CSV  | 12 KB  | uploaded | Jane Doe
```

### List Flags

| Flag                 | Default    | Description                                            |
| -------------------- | ---------- | ------------------------------------------------------ |
| `--name`, `-n`       | —          | Filter by file name (partial match)                    |
| `--extension`, `-e`  | —          | Filter by file extension (e.g. `pdf`, `xlsx`)          |
| `--mime-type`        | —          | Filter by MIME type                                    |
| `--from-date`        | —          | Filter from date (YYYY-MM-DD)                          |
| `--to-date`          | —          | Filter to date (YYYY-MM-DD)                            |
| `--status`           | `uploaded` | Filter by status                                       |
| `--owner-id`         | —          | Filter by owner user UUID                              |
| `--sort-by`, `-s`    | —          | Sort by: `name`, `extension`, `status`, `size`, `date` |
| `--sort-order`, `-o` | `asc`      | Sort order: `asc` or `desc`                            |
| `--page`             | `1`        | Page number                                            |
| `--size`             | `50`       | Page size                                              |
| `--org`              | —          | Organization ID override                               |

### List Examples

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Find PDF files
dcy file list --extension pdf

# Files uploaded in a date range
dcy file list --from-date 2024-01-01 --to-date 2024-03-31

# Sort by size (largest first)
dcy file list --sort-by size --sort-order desc

# Search by name
dcy file list --name "invoice"

# JSON output for scripting
dcy file list --format json | jq '.[] | {id, name, status}'
```

***

## Show File Details

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy file show <file-id>
```

Output:

```
ID: 550e8400-e29b-41d4-a716-446655440000
Name: invoice-march
Extension: PDF
MIME Type: application/pdf
Size: 245 KB
Status: uploaded
Owner: Jane Doe
Owner Email: jane@company.com
URL: https://...
Tags: electricity, q1
Created: 2024-03-15
Updated: 2024-03-15
```

***

## Delete a File

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Interactive confirmation
dcy file delete <file-id>

# Skip confirmation
dcy file delete <file-id> --yes
```

| Flag          | Default | Description              |
| ------------- | ------- | ------------------------ |
| `--yes`, `-y` | `false` | Skip confirmation prompt |
| `--org`       | —       | Organization ID override |

***

## Recover a Deleted File

Restore a previously deleted file:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy file recover <file-id>
```

***

## Retry File Processing

If a file was uploaded and classified but hasn't produced a reading, re-queue it for processing:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy file process <file-id>
```

Output:

```
processing event queued for file 550e8400-...
```

This sends a `PROCESS_DOCUMENT` event to the backend pipeline. Use it when a file is stuck in `uploaded` status or when the extraction pipeline needs to re-run.

***

## File Readings

File readings contain the data extracted from uploaded documents by the AI classification and parsing pipeline.

### List Readings

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy file reading list

# Short alias
dcy file reading ls
```

Output:

```
Showing 5 of 15 file readings
550e8400-... | invoice-march   | electricity | linked=true  | reading=completed | reading_id=abc123-...
661f9511-... | utility-bill    | natural_gas | linked=true  | reading=completed | reading_id=def456-...
772a0622-... | waste-cert-q1   | waste       | linked=false | reading=completed | reading_id=ghi789-...
883b1733-... | gas-invoice     | natural_gas | linked=false | reading=pending   | reading_id=jkl012-...
994c2844-... | water-readings  | water       | linked=false | reading=(none)    | reading_id=
```

### List Reading Flags

| Flag           | Default | Description                                       |
| -------------- | ------- | ------------------------------------------------- |
| `--file-id`    | —       | Filter by file ID (repeatable for multiple files) |
| `--folder-id`  | —       | Filter by folder ID                               |
| `--project-id` | —       | Filter by project ID                              |
| `--linked`     | —       | Filter by linked status: `true` or `false`        |
| `--name`       | —       | Filter by file name                               |
| `--category`   | —       | Filter by reading category (repeatable)           |
| `--page`       | `1`     | Page number                                       |
| `--size`       | `50`    | Page size                                         |
| `--org`        | —       | Organization ID override                          |

### List Reading Examples

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Filter by category
dcy file reading list --category electricity
dcy file reading list --category water --category waste

# Find unlinked readings (not yet converted to records)
dcy file reading list --linked false

# Filter by specific file
dcy file reading list --file-id <file-id>

# Filter by folder
dcy file reading list --folder-id <folder-id>

# JSON output
dcy file reading list --format json | jq '.[] | select(.linked == false) | .id'
```

### Show a File's Reading

View the parsed reading content for a specific file:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy file reading show <file-id>
```

Output:

```
File ID: 550e8400-e29b-41d4-a716-446655440000
Name: invoice-march
Category: electricity
Status: uploaded
Linked: true
Tags: electricity, q1
Reading ID: abc123-def456-...
Reading Status: completed
Reading Items: 3
```

***

## Correct Reading Content

If the extracted data has errors, prepare a JSON file with the corrected content and update the reading:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy file reading update <file-reading-id> --content-file ./reading.json
```

| Flag             | Required | Description                            |
| ---------------- | -------- | -------------------------------------- |
| `--content-file` | Yes      | Path to JSON file with corrected items |
| `--org`          | No       | Organization ID override               |

The JSON file can be in any of these formats:

**Full content object:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "content": {
    "items": [
      {"type": "electricity", "start_date": "2024-01-01", "consumption": 4500}
    ]
  }
}
```

**Items wrapper:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "items": [
    {"type": "electricity", "start_date": "2024-01-01", "consumption": 4500}
  ]
}
```

**Raw items array:**

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
[
  {"type": "electricity", "start_date": "2024-01-01", "consumption": 4500}
]
```

***

## Create Records from Readings

Convert a parsed reading into invoices or waste records, assigning facility allocations:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Single facility (100%)
dcy file reading create-records <file-reading-id> \
  --facility <facility-id>=1.0
```

Output:

```
Created 3 records from file reading abc123-...
rec-001-... | electricity | facility=fac-001-...
rec-002-... | electricity | facility=fac-001-...
rec-003-... | electricity | facility=fac-001-...
```

### Split Across Multiple Facilities

Allocate the reading's data across facilities by percentage (total must be ≤ 1.0):

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy file reading create-records <file-reading-id> \
  --facility <facility-a>=0.6 \
  --facility <facility-b>=0.4 \
  --project-id <project-id>
```

| Flag           | Required | Description                                                  |
| -------------- | -------- | ------------------------------------------------------------ |
| `--facility`   | Yes      | Facility allocation as `facility-id=percentage` (repeatable) |
| `--project-id` | No       | Project UUID to link created records                         |
| `--org`        | No       | Organization ID override                                     |

<Warning>
  The backend currently processes one file reading per `create-records` request.
</Warning>

***

## Typical Workflows

### Upload and Process Invoice

Upload an invoice PDF, wait for extraction, then create invoice records:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# 1. Upload the file
FILE_ID=$(dcy file upload ./invoice.pdf --project-id "$PROJECT_ID" --format json | jq -r '.id')
echo "Uploaded: $FILE_ID"

# 2. Check if the reading is ready (may take a few seconds)
dcy file reading show $FILE_ID

# 3. If no reading yet, re-trigger processing
dcy file process $FILE_ID

# 4. Once reading is complete, get the reading ID
READING_ID=$(dcy file reading list --file-id $FILE_ID --format json | jq -r '.[0].reading.id')

# 5. Create invoice records from the reading
dcy file reading create-records $READING_ID --facility "$FACILITY_ID"=1.0
```

### Batch Upload Documents

Upload all PDFs in a directory:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
for file in ./invoices/*.pdf; do
  echo "Uploading $file..."
  dcy file upload "$file" --folder-id "$FOLDER_ID" --format json
done
```

### Find Unlinked Readings

Identify files that have been parsed but not yet converted to records:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# List unlinked readings
dcy file reading list --linked false --format json \
  | jq '.[] | {id, name, category, reading_id: .reading.id}'
```

### Correct and Re-create Records

Fix extracted data and create records from the corrected reading:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# 1. Export current reading content
dcy file reading show <file-id> --format json | jq '.reading.content' > reading.json

# 2. Edit reading.json to fix errors

# 3. Update the reading
dcy file reading update <reading-id> --content-file reading.json

# 4. Create records from the corrected reading
dcy file reading create-records <reading-id> --facility <facility-id>=1.0
```

### CI/CD Automation

Upload files from a CI pipeline using API key authentication:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
#!/usr/bin/env bash
set -euo pipefail

export DCYCLE_API_KEY="$API_KEY"
export DCYCLE_ORG_ID="$ORG_ID"

for file in ./artifacts/*.pdf; do
  result=$(dcy file upload "$file" --project-id "$PROJECT_ID" --format json)
  echo "Uploaded $(basename "$file"): $(echo "$result" | jq -r '.id')"
done
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Invoices" icon="file-invoice" href="/cli/invoices">
    Manage energy invoices created from file readings
  </Card>

  <Card title="Data Imports" icon="upload" href="/cli/imports">
    Bulk import CSV/Excel with guided mapping and validation
  </Card>

  <Card title="Projects" icon="clipboard-list" href="/cli/projects">
    Organize files and emissions data into sustainability projects
  </Card>

  <Card title="Configuration" icon="gear" href="/cli/configuration">
    Set up environments and API keys for automation
  </Card>

  <Card title="MCP Tools" icon="robot" href="/mcp/files">
    Query files from AI assistants via MCP
  </Card>
</CardGroup>
