> For the complete documentation index, see [llms.txt](https://docs.viesus.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.viesus.com/reference/cloud-api/uploading.md).

# Uploading

Upload images and PDFs to VIESUS Cloud via URL or signed upload URL. Response fields, retention, and deletion.

Every enhancement starts with an upload. The upload creates a persistent file record that you reference by `id` in subsequent enhancement requests.

***

## Which method to use

| Your file is...                 | Method                                          |
| ------------------------------- | ----------------------------------------------- |
| At a reachable public URL       | [Upload from URL](#upload-from-a-url) — simpler |
| On your server or local machine | [Signed upload URL](#upload-with-a-signed-url)  |

***

## Upload from a URL

The simplest method. VIESUS Cloud fetches the file directly from the URL you provide.

```graphql
mutation {
  createUploadFromUrl(
    input: {
      url: "https://www.example.com/photo.jpg"
    }
  ) {
    id
    status
    filesize
    mimetype
    extension
    originalFilename
    filename
    width
    height
    url
    startedAt
    finishedAt
    duration
  }
}
```

Save the returned `id` — you need it to trigger enhancements.

**curl example:**

```bash
curl -X POST https://api.viesus.cloud/graphql \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR-API-KEY" \
  -d '{
    "query": "mutation { createUploadFromUrl(input: { url: \"https://example.com/photo.jpg\" }) { id status } }"
  }'
```

***

## Upload with a signed URL

For files on your server, local machine, or user uploads that go directly from the browser to VIESUS Cloud storage. This is a three-step process.

{% stepper %}
{% step %}

#### Request a signed URL

```graphql
mutation {
  createSignedUploadUrl(
    input: {
      filename: "photo.jpg"
      filesize: 2048000
      mimetype: "image/jpeg"
    }
  ) {
    uploadId
    uploadUrl
  }
}
```

{% hint style="danger" %}
`filesize` and `mimetype` must match the actual file. Incorrect values cause the upload to fail at the final step.
{% endhint %}
{% endstep %}

{% step %}

#### PUT the file to the signed URL

Use the `uploadUrl` from the previous step to PUT the file directly to storage:

**Node.js:**

```js
const fs = require('fs');

const filePath = './photo.jpg';
const fileBuffer = fs.readFileSync(filePath);
const stats = fs.statSync(filePath);

await fetch(uploadUrl, {
  method: 'PUT',
  body: fileBuffer,
  headers: {
    'Content-Type': 'image/jpeg',
    'Content-Length': stats.size.toString(),
  },
});
```

**Browser (file input):**

```js
async function putFile(uploadUrl, file) {
  await fetch(uploadUrl, {
    method: 'PUT',
    body: await file.arrayBuffer(),
    headers: {
      'Content-Type': file.type,
    },
  });
}
```

**curl:**

```bash
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: image/jpeg" \
  --data-binary @photo.jpg
```

{% endstep %}

{% step %}

#### Complete the upload

Finalize using the `uploadId` from the first step:

```graphql
mutation {
  completeSignedUpload(id: "uploadId") {
    id
    status
    filesize
    mimetype
    width
    height
    url
    startedAt
    finishedAt
    duration
  }
}
```

The returned `id` is the upload ID for all subsequent enhancement requests.
{% endstep %}
{% endstepper %}

***

## Upload response fields

<table><thead><tr><th width="246.800048828125">Field</th><th>Description</th></tr></thead><tbody><tr><td><code>id</code></td><td>Upload identifier — required for enhancement mutations</td></tr><tr><td><code>status</code></td><td>Upload state</td></tr><tr><td><code>filesize</code></td><td>File size in bytes</td></tr><tr><td><code>mimetype</code></td><td>Detected MIME type</td></tr><tr><td><code>extension</code></td><td>File extension</td></tr><tr><td><code>originalFilename</code></td><td>Filename as uploaded</td></tr><tr><td><code>filename</code></td><td>Storage filename</td></tr><tr><td><code>width</code> / <code>height</code></td><td>Image dimensions in pixels (0 for PDFs)</td></tr><tr><td><code>url</code></td><td>URL to access the original uploaded file</td></tr><tr><td><code>startedAt</code> / <code>finishedAt</code></td><td>Upload timestamps (ISO 8601)</td></tr><tr><td><code>duration</code></td><td>Upload processing time in milliseconds</td></tr></tbody></table>

***

## Upload retention

Uploads are stored for **30 days** by default, then automatically deleted. To change the default retention for new uploads:

```graphql
mutation {
  updateFileRetention(days: 7) {
    uploadRetentionDays
  }
}
```

This setting applies to uploads made after the change — existing uploads keep their original retention.

To delete an upload immediately:

```graphql
mutation {
  deleteUploads(ids: ["upload-id-1", "upload-id-2"]) {
    deletedUploadIds
  }
}
```

***

## Multiple enhancements from one upload

The same upload can be enhanced multiple times with different parameters. You do not need to re-upload the file:

```graphql
mutation EnhanceA {
  createEnhancedImage(uploadId: "upload-id", input: { mode: ENHANCE }) {
    id status
  }
}

mutation EnhanceB {
  createEnhancedImage(uploadId: "upload-id", input: { mode: ENHANCE, upscalingFactor: X2 }) {
    id status
  }
}
```

This is useful for generating multiple output variants (e.g., with and without upscaling) without paying upload costs twice.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.viesus.com/reference/cloud-api/uploading.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
