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

# Upload File

> Upload a file and get a public URL.

Upload a file to StashFyle. Returns file metadata including a public CDN URL (or null for private files).

## Request

<ParamField body="file" type="file" required>
  The file to upload. Max size depends on your plan (10MB-500MB).
</ParamField>

<ParamField body="folder" type="string">
  Optional folder path to organize files. Example: `images/avatars`
</ParamField>

<ParamField body="private" type="boolean" default="false">
  Set to `true` to make the file private (requires secret key). Private files need signed URLs to access.
</ParamField>

<ParamField body="expires" type="string">
  Auto-delete after this duration. Format: `1h`, `7d`, `30d`. Omit for permanent storage.
</ParamField>

## Response

<ResponseField name="id" type="string" required>
  Unique file identifier. Example: `f_abc123xyz`
</ResponseField>

<ResponseField name="url" type="string">
  Public CDN URL. `null` for private files.
</ResponseField>

<ResponseField name="name" type="string" required>
  Original filename.
</ResponseField>

<ResponseField name="folder" type="string">
  Folder path, or `null` if uploaded to root.
</ResponseField>

<ResponseField name="size" type="integer" required>
  File size in bytes.
</ResponseField>

<ResponseField name="type" type="string">
  MIME type. Example: `image/jpeg`
</ResponseField>

<ResponseField name="private" type="boolean" required>
  Whether the file is private.
</ResponseField>

<ResponseField name="expires_at" type="string">
  ISO 8601 expiration timestamp, or `null` if permanent.
</ResponseField>

<ResponseField name="created_at" type="string" required>
  ISO 8601 creation timestamp.
</ResponseField>

## Examples

### Basic Upload

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.stashfyle.com/v1/upload \
    -H "Authorization: Bearer sk_live_xxx" \
    -F "file=@photo.jpg"
  ```

  ```javascript JavaScript theme={null}
  const form = new FormData();
  form.append('file', file);

  const response = await fetch('https://api.stashfyle.com/v1/upload', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer sk_live_xxx' },
    body: form
  });

  const data = await response.json();
  console.log(data.url);
  ```

  ```python Python theme={null}
  import requests

  with open('photo.jpg', 'rb') as f:
      response = requests.post(
          'https://api.stashfyle.com/v1/upload',
          headers={'Authorization': 'Bearer sk_live_xxx'},
          files={'file': f}
      )

  print(response.json()['url'])
  ```

  ```go Go theme={null}
  file, _ := os.Open("photo.jpg")
  defer file.Close()

  body := &bytes.Buffer{}
  writer := multipart.NewWriter(body)
  part, _ := writer.CreateFormFile("file", "photo.jpg")
  io.Copy(part, file)
  writer.Close()

  req, _ := http.NewRequest("POST", "https://api.stashfyle.com/v1/upload", body)
  req.Header.Set("Authorization", "Bearer sk_live_xxx")
  req.Header.Set("Content-Type", writer.FormDataContentType())

  resp, _ := http.DefaultClient.Do(req)
  ```
</CodeGroup>

```json Response theme={null}
{
  "id": "f_abc123xyz",
  "url": "https://cdn.stashfyle.com/live/user_123/f_abc123xyz/photo.jpg",
  "name": "photo.jpg",
  "folder": null,
  "size": 248000,
  "type": "image/jpeg",
  "private": false,
  "expires_at": null,
  "created_at": "2024-01-15T10:30:00Z"
}
```

### Upload to Folder

```bash theme={null}
curl -X POST https://api.stashfyle.com/v1/upload \
  -H "Authorization: Bearer sk_live_xxx" \
  -F "file=@avatar.png" \
  -F "folder=users/avatars"
```

### Private File

```bash theme={null}
curl -X POST https://api.stashfyle.com/v1/upload \
  -H "Authorization: Bearer sk_live_xxx" \
  -F "file=@document.pdf" \
  -F "private=true"
```

```json Response theme={null}
{
  "id": "f_xyz789abc",
  "url": null,
  "name": "document.pdf",
  "private": true,
  ...
}
```

### Auto-Expiring File

```bash theme={null}
curl -X POST https://api.stashfyle.com/v1/upload \
  -H "Authorization: Bearer sk_live_xxx" \
  -F "file=@temp-report.pdf" \
  -F "expires=7d"
```

```json Response theme={null}
{
  "id": "f_temp123",
  "expires_at": "2024-01-22T10:30:00Z",
  ...
}
```

## Errors

| Code                     | Status | Description                        |
| ------------------------ | ------ | ---------------------------------- |
| `unauthorized`           | 401    | Invalid or missing API key         |
| `forbidden`              | 403    | Public key with invalid origin     |
| `bad_request`            | 400    | Missing file or invalid parameters |
| `file_too_large`         | 413    | File exceeds plan limit            |
| `storage_limit_exceeded` | 413    | Storage quota exceeded             |
| `grace_period`           | 403    | Account in grace period            |
| `rate_limit_exceeded`    | 429    | Too many requests                  |
