# Completes a direct external upload

`POST /uploads/complete-external-upload.json`

Completes an external upload initialized with /get-presigned-put. The
file will be moved from its temporary location in external storage to
a final destination in the S3 bucket. An Upload record will also be
created in the database in most cases.

If a sha1-checksum was provided in the initial request it will also
be compared with the uploaded file in storage to make sure the same
file was uploaded. The file size will be compared for the same reason.

You must have the correct permissions and CORS settings configured in your
external provider. We support AWS S3 as the default. See:

https://meta.discourse.org/t/-/210469#s3-multipart-direct-uploads-4.

An external file store must be set up and `enable_direct_s3_uploads` must
be set to true for this endpoint to function.



Authentication: no security requirement declared for this operation.

Request body: application/json

Type: any

- `unique_identifier` (required)
  Type: string
  
  The unique identifier returned in the original /generate-presigned-put
  request.
  
  Example:
  
  ```json
  "66e86218-80d9-4bda-b4d5-2b6def968705"
  ```

- `for_private_message` (optional)
  Type: string
  
  Optionally set this to true if the upload is for a
  private message.
  
  Example:
  
  ```json
  "true"
  ```

- `for_site_setting` (optional)
  Type: string
  
  Optionally set this to true if the upload is for a
  site setting.
  
  Example:
  
  ```json
  "true"
  ```

- `pasted` (optional)
  Type: string
  
  Optionally set this to true if the upload was pasted
  into the upload area. This will convert PNG files to JPEG.
  
  Example:
  
  ```json
  "true"
  ```

Additional properties: false

Responses:

- 200: external upload initialized

Content type: application/json

Type: any

- `id` (required)
  Type: integer

- `url` (required)
  Type: string

- `original_filename` (required)
  Type: string

- `filesize` (required)
  Type: integer

- `width` (required)
  Type: integer

- `height` (required)
  Type: integer

- `thumbnail_width` (required)
  Type: integer

- `thumbnail_height` (required)
  Type: integer

- `extension` (required)
  Type: string

- `short_url` (required)
  Type: string

- `short_path` (required)
  Type: string

- `retain_hours` (required)
  Type: string; nullable

- `human_filesize` (required)
  Type: string

- `dominant_color` (optional)
  Type: string; nullable

- `thumbnail` (optional)
  Type: object; nullable
  
  - `id` (optional)
    Type: integer
  
  - `upload_id` (optional)
    Type: integer
  
  - `url` (optional)
    Type: string
  
  - `extension` (optional)
    Type: string
  
  - `width` (optional)
    Type: integer
  
  - `height` (optional)
    Type: integer
  
  - `filesize` (optional)
    Type: integer
  
  Additional properties: false

- `optimized_video` (optional)
  Type: object; nullable
  
  - `id` (optional)
    Type: integer
  
  - `upload_id` (optional)
    Type: integer
  
  - `url` (optional)
    Type: string
  
  - `extension` (optional)
    Type: string
  
  - `filesize` (optional)
    Type: integer
  
  - `sha1` (optional)
    Type: string
  
  - `original_filename` (optional)
    Type: string
  
  Additional properties: false

Additional properties: false

## Examples

### cURL

```bash
curl -X POST 'https://discourse.example.com/uploads/complete-external-upload.json' \
  -H 'Content-Type: application/json' \
  --data-raw '{
  "unique_identifier": "66e86218-80d9-4bda-b4d5-2b6def968705",
  "for_private_message": "true",
  "for_site_setting": "true",
  "pasted": "true"
}'
```

### JavaScript

```javascript
const body = `{
  "unique_identifier": "66e86218-80d9-4bda-b4d5-2b6def968705",
  "for_private_message": "true",
  "for_site_setting": "true",
  "pasted": "true"
}`;

const response = await fetch('https://discourse.example.com/uploads/complete-external-upload.json', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body,
});

const data = await response.text();
```

### Python

```python
import requests

body = '''{
  "unique_identifier": "66e86218-80d9-4bda-b4d5-2b6def968705",
  "for_private_message": "true",
  "for_site_setting": "true",
  "pasted": "true"
}'''

response = requests.post(
    'https://discourse.example.com/uploads/complete-external-upload.json',
    data=body.encode('utf-8'),
    headers={
        'Content-Type': 'application/json',
    },
)
print(response.text)
```
