> This page is for version v1 (default).
> For other versions, use one of these documentation indexes:
> - v1 (default): https://developers.truemed.com/v-1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.truemed.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.truemed.com/_mcp/server.

# Upload evidence files

> How to upload dispute evidence files through the Files API and reference them from a counter.

Evidence files — receipts, shipping documentation, screenshots — are uploaded through the Files API and then referenced
from a counter by their `file_id`. Files are uploaded directly to storage with a short-lived presigned URL and are ready
to attach to a counter as soon as the upload completes.

## The upload flow

```mermaid
sequenceDiagram
  participant You
  participant Truemed
  participant Storage
  You->>Truemed: POST /api/v1/files/create (filename, content_type, size_bytes, purpose)
  Truemed-->>You: file_id + presigned upload_url + upload_fields
  You->>Storage: POST file to upload_url (multipart/form-data)
  Storage-->>You: 204 No Content
  You->>Truemed: reference file_id in a counter's evidence_items
```

## 1. Request an upload slot

`POST /api/v1/files/create` reserves a file and returns a presigned upload target. `purpose` is `dispute_evidence`.

```bash
curl -s -X POST "https://dev-api.truemed.com/api/v1/files/create" \
  -H "Authorization: Bearer $TRUEMED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "receipt.pdf",
    "content_type": "application/pdf",
    "size_bytes": 482113,
    "purpose": "dispute_evidence"
  }'
```

```json
{
  "file_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "upload_url": "https://s3.amazonaws.com/...",
  "upload_fields": { "key": "...", "policy": "...", "x-amz-signature": "..." },
  "expires_at": "2026-06-29T18:10:00Z"
}
```

The `upload_url` expires 10 minutes after creation. For `dispute_evidence`, `content_type` must be one of
`application/pdf`, `image/png`, `image/jpeg`, or `image/tiff`, and `size_bytes` must be at most **5 MiB** (5,242,880
bytes). A request outside these limits is rejected before an upload slot is issued.

## 2. Upload the file to storage

POST the file to `upload_url` as `multipart/form-data`, including every key from `upload_fields` **before** the file part.

```bash
curl -s -X POST "$UPLOAD_URL" \
  -F "key=$KEY" \
  -F "policy=$POLICY" \
  -F "x-amz-signature=$SIGNATURE" \
  -F "file=@receipt.pdf"
```

## 3. Read it back (optional) and reference it

The file is ready to attach as soon as the upload completes. `GET /api/v1/files/{file_id}` returns its metadata and a
short-lived (5-minute) presigned `download_url` if you need to read it back.

```bash
curl -s "https://dev-api.truemed.com/api/v1/files/f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Authorization: Bearer $TRUEMED_API_KEY"
```

Reference the `file_id` from a counter's `evidence_items` (see
[Respond with Evidence](/guides/setup/api/disputes/respond-with-evidence)).

## Rules to know

> **Warning**
>
> **Files must belong to you.** Every `file_id` you attach to a counter must have been created by your own sales channel.
> A `file_id` owned by another channel is rejected (`422`).

* **Expiry.** Freshly uploaded files have a short orphan lifetime and age out if never used. Submitting a counter is what
  extends a referenced file's retention to the post-resolution window — so attach-and-submit, don't upload-and-forget.