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

# Transfer API

> Import remote files, extract ZIP archives, and move cloud-folder contents into Convertly Storage.

The Transfer API moves external files into Convertly. Use it to fetch a public URL, store a ZIP archive as files, or import a folder from Google Drive, S3, or Dropbox.

For production workloads, prefer `destination: "convertly-storage"`. Convertly can store the result, return signed download URLs, preserve extracted ZIP paths as folders, and keep large imports away from your app server.

Single-file URL transfers into Convertly Storage are asynchronous by default. The request creates a transfer job and returns `202 Accepted` with a `jobId`; poll `GET /api/jobs/{jobId}` or subscribe to job updates to read the stored file result when it completes.

## Public URL transfer

```bash theme={"system"}
curl -X POST "https://convertly.sh/api/transfer" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceUrl": "https://example.com/assets/product-photo.png",
    "destination": "convertly-storage",
    "filename": "product-photo.png"
  }'
```

The response is queued:

```json theme={"system"}
{
  "jobId": "job_123",
  "status": "pending",
  "mode": "async"
}
```

When the job completes, `GET /api/jobs/job_123` includes the stored file metadata and signed download URL in `results`.

`destination: "download"` returns the fetched file as the response body. `destination: "convertly-storage"` stores the file asynchronously by default. Set `"async": false` only for small request/response workflows where you explicitly want the API request to wait for storage.

## ZIP transfer and extract

Set `extract: true` to download a ZIP archive, extract it, and save each entry into Convertly Storage.

```bash theme={"system"}
curl -X POST "https://convertly.sh/api/transfer" \
  -H "Authorization: Bearer $CONVERTLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceUrl": "https://example.com/client-assets.zip",
    "destination": "convertly-storage",
    "extract": true,
    "extractOptions": {
      "folderName": "Client assets",
      "preservePaths": true,
      "maxFiles": 500
    }
  }'
```

Convertly creates a folder, preserves ZIP subfolders by default, stores each extracted file, and returns the stored file records.

## Cloud folder import

Use `cloudSource` instead of `sourceUrl` to import files from a provider API.

### Google Drive

Google Drive imports use the Google Drive account connected in the Convertly dashboard.

```json theme={"system"}
{
  "destination": "convertly-storage",
  "cloudSource": {
    "provider": "google-drive",
    "folderId": "1abcDriveFolderId",
    "recursive": true
  }
}
```

Use `fileId` instead of `folderId` to import a single Google Drive file.

### S3

S3 imports use request-scoped credentials. The credentials are used for the import request and are not stored.

```json theme={"system"}
{
  "destination": "convertly-storage",
  "cloudSource": {
    "provider": "s3",
    "bucket": "product-assets",
    "prefix": "spring-catalog/",
    "region": "us-east-1",
    "accessKeyId": "AKIA...",
    "secretAccessKey": "...",
    "recursive": true
  }
}
```

Use `key` instead of `prefix` to import one S3 object.

### Dropbox

Dropbox imports use a request-scoped Dropbox access token.

```json theme={"system"}
{
  "destination": "convertly-storage",
  "cloudSource": {
    "provider": "dropbox",
    "path": "/Client Assets",
    "accessToken": "sl...",
    "recursive": true
  }
}
```

## Request fields

| Field                           | Type    | Description                                                                                                       |
| ------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
| `sourceUrl`                     | string  | Public `http` or `https` URL. Use this or `cloudSource`, not both.                                                |
| `cloudSource`                   | object  | Provider import configuration for Google Drive, S3, or Dropbox.                                                   |
| `destination`                   | string  | `download` or `convertly-storage`. Cloud and extract transfers require storage.                                   |
| `filename`                      | string  | Optional filename for public URL transfers.                                                                       |
| `contentType`                   | string  | Optional content type override.                                                                                   |
| `async`                         | boolean | For single-file URL transfers into Convertly Storage, queue the transfer as a background job. Defaults to `true`. |
| `extract`                       | boolean | Extract a ZIP archive into Convertly Storage.                                                                     |
| `extractOptions.preservePaths`  | boolean | Preserve ZIP subfolders. Defaults to `true`.                                                                      |
| `extractOptions.folderName`     | string  | Name of the root folder created in Convertly Storage.                                                             |
| `extractOptions.targetFolderId` | string  | Parent Convertly folder for extracted or imported files.                                                          |
| `extractOptions.maxFiles`       | number  | Maximum extracted files. Defaults to `500`.                                                                       |
| `extractOptions.maxEntryBytes`  | number  | Maximum extracted size for one ZIP entry.                                                                         |
| `extractOptions.maxTotalBytes`  | number  | Maximum total extracted size.                                                                                     |

## Response

Queued storage transfers return a job envelope. Completed transfer jobs expose the stored file in the job `results`. Synchronous storage transfers, ZIP extraction, and cloud folder imports return stored file or folder metadata immediately.

```json theme={"system"}
{
  "folder": {
    "id": "folder_123",
    "name": "Client assets"
  },
  "files": [
    {
      "id": "file_123",
      "filename": "hero.webp",
      "mimeType": "image/webp",
      "sizeBytes": 482391,
      "storagePath": "user-id/uploaded/...",
      "downloadUrl": "https://..."
    }
  ],
  "usage": {
    "processedTransferBytes": 964782,
    "pricingBucket": "processed_transfer"
  }
}
```

## Pricing

Transfer API usage counts against **monthly processed transfer**. Convertly meters source read plus destination write, so a 100 MB file stored in Convertly counts as about 200 MB of processed transfer. ZIP extraction counts the archive download plus extracted bytes written to storage.

Stored files count toward your HDAM storage quota. Storage overage is billed on monthly peak overage growth when enabled. Quotas and overage behavior: [Limits](/limits#file-and-storage-limits) and [Limits → Media API](/limits#media-api-limits).

## Safety and scaling

Convertly blocks localhost, private-network, and non-HTTP source URLs. ZIP extraction rejects path traversal, skips directory entries, and enforces file-count and extracted-size limits.

Single-file URL-to-storage transfers run in the background worker. Convertly streams the remote response to temporary disk, then streams the file into Convertly Storage instead of buffering the whole file in the web request.

The archive path is designed to avoid loading the entire ZIP into memory: Convertly downloads the archive to temporary disk, then extracts entries one at a time. Cloud imports process files sequentially and cap imports at 500 files per request.
