---
title: get_file_upload
description: Read an uploaded file's status, its SHA-256 and the catalog its conversion wrote, or hold the call open until the conversion finishes.
updated: 2026-09-17
tools: [get_file_upload]
---

Reads one uploaded file by the `upload` id
[`create_file_upload`](/reference/mcp-tools/create-file-upload) returned: where it
is, and once it is converted, what Dashies found in it.

Behaviour hints for clients: read-only, not open-world.

## Parameters

| Parameter | Type | Required | Notes |
|---|---|---|---|
| `upload` | string | yes | The upload id `create_file_upload` returned. |
| `wait_seconds` | integer | no | Default 0. How long the call may hold itself open while the upload is still moving, 0 to 45. See [Waiting for a conversion](#waiting-for-a-conversion). |
| `workspace` | string | no | Workspace slug, only for a legacy connection authorized for no workspace. |

## Status

| Status | Meaning |
|---|---|
| `pending` | Waiting for the file. Run the command `create_file_upload` returned before its ticket expires. |
| `receiving` | The file is arriving. |
| `uploaded`, `converting` | The file arrived and is being converted. |
| `ready` | Converted. The catalog is in the response. |
| `failed` | The upload or its conversion failed. `failure` and `failure_detail` say why, and `failure_detail` decides what to do next: where it names an override, re-convert with `reconvert_of` rather than re-uploading (see [Build a dashboard from a file](/guides/upload-a-file)), reading WHAT it asks for, sentence by sentence rather than by token - an `unsupported_encoding` or `header_refused` sentence names an override to send, while an `override_refused` sentence is the conversion refusing a value you already sent and may still name a DIFFERENT override to add ("add the sheets override naming one", while refusing `names`), so read it for what to change or add and never re-send the refused value; otherwise do what it says, which is usually to fix the file or to send it again. A failed upload stays re-convertible while its original bytes are kept. |
| `expired` | The ticket expired before a file arrived. |
| `deleted` | The upload was deleted. |

## Returns

```text
Upload 0b6f0c1e-4c1d-4f55-9a57-2a1f0f7d9e21 ("sales.csv"): ready
- Ready. The catalog in the JSON block lists each table's columns with their declared types and a profile of their values.
- Size: 48213 bytes
- SHA-256: 9f2c... (compare it with the output of shasum -a 256 on the file)
- Tables:
  - sales: 1200 rows, 8 columns
- Waited: 9044 ms (wait_outcome: changed)

BEGIN_JSON
{"upload":"0b6f0c1e-...","filename":"sales.csv","status":"ready","declared_bytes":48213,"bytes":48213,"sha256":"9f2c...","catalog":{"format":1,"source":{},"tables":[],"warnings":[]},"failure":null,"failure_detail":null,"referenced_by":{"dashboards":[],"versions":[]},"created_at":"...","ticket_expires_at":"...","ready_at":"...","failed_at":null,"waited_ms":9044,"wait_outcome":"changed"}
END_JSON
```

`sha256` is computed by the conversion over the bytes Dashies stored, so it can be
compared with `shasum -a 256` on the original file.

The `catalog` lists one table per CSV file and one per non-empty sheet of a
workbook. Each column carries its name as it appeared in the header, the type it
was declared as after reading the **whole** file, whether any value was null, a
profile of its values, and any findings that kept it as text, such as numbers
with leading zeros or dates whose day and month cannot be told apart.

`referenced_by` lists the dashboards and saved versions that use the upload.

## Waiting for a conversion

Pass `wait_seconds` and, while the upload is `receiving`, `uploaded` or
`converting`, the call holds itself open, re-reads every few seconds, and returns
as soon as the status changes or the budget runs out:

| Field | Meaning |
|---|---|
| `waited_ms` | How long the call held itself open, measured on the server. `0` when it did not wait. |
| `wait_outcome` | `changed`: the status changed. `budget_elapsed`: still in progress; call again with `wait_seconds`. `not_waiting`: nothing was in progress, or `wait_seconds` was 0. |

A `pending` upload is not waited on, because only running the `curl` command moves
it. The cap of 45 seconds is the MCP client's own timeout on a single tool call,
the same cap [`get_refresh_status`](/reference/mcp-tools/get-refresh-status)
uses.

## Errors

- `No upload with that id in this workspace.` for an unknown id, an upload in
  another workspace, or an upload the caller cannot see. All three get the same
  answer.
- A missing or malformed `upload`, or a `wait_seconds` outside 0 to 45.

## Scope

Which workspace the call reads comes from how this MCP connection was authorized.
Any member of that workspace may read its uploads.
