---
title: Upload and Replace Assets
description: Upload and replace assets in Storyblok.
url: https://storyblok.com/docs/api/management/assets/upload-and-replace-assets
---

# Upload and Replace Assets

## Upload

Uploading assets to Storyblok is a three-step process.

1.  Get signed response
    
    Use the [get signed response endpoint](/docs/api/management/assets/get-signed-response) to request a signed response object for uploading the asset.
    
2.  Upload asset
    
    Upload the asset to Amazon S3 using the `post_url` included in the signed response object. The content type of the request has to be `multipart/form-data`. Everything in the `fields` object of the signed response object needs to be included in the form. Lastly, add the file to be uploaded to the form.
    
    **Example (curl):**
    
    ```bash
    curl --request POST \
    --url https://s3.amazonaws.com/a.storyblok.com \
    --header 'content-type: multipart/form-data' \
    --form key=f/184738/9fe59e1868/mars.jpg \
    --form policy=eyJleHBpcmF0aW9uIjoiMjAyNS0wOS0wNVQxMzo0MToyNFoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJhLnN0b3J5Ymxvay5jb20ifSx7ImFjbCI6InB1YmxpYy1yZWFkIn0seyJDYWNoZS1Db250cm9sIjoicHVibGljLCBtYXgtYWdlPTMxNTM2MDAwIn0seyJDb250ZW50LVR5cGUiOiJpbWFnZS9qcGVnIn0seyJrZXkiOiJmLzE4NDczOC85ZmU1OWUxODY4L21hcnMuanBnIn0seyJFeHBpcmVzIjoiU2F0LCAwNSBTZXAgMjAyNiAxMzozMToyNCBHTVQifSxbImNvbnRlbnQtbGVuZ3RoLXJhbmdlIiwxLDUyNDI4Nzk5OTldLHsieC1hbXotY3JlZGVudGlhbCI6IkFLSUFJVTYyN0VOVVFUNFJXMjNBLzIwMjUwOTA1L3VzLWVhc3QtMS9zMy9hd3M0X3JlcXVl \
    --form x-amz-algorithm=AWS4-HMAC-SHA256 \
    --form x-amz-credential=AKIAIU627ENUQT4RW23A/20250905/us-east-1/s3/aws4_request \
    --form x-amz-date=20250905T133124Z \
    --form x-amz-signature=df14c58d762e95225b204ed878cdcff4b024920bfa7be86a871e44b48ead2d30 \
    --form acl=public-read \
    --form 'Expires=Sat, 05 Sep 2026 13:31:24 GMT' \
    --form 'Cache-Control=public, max-age=31536000' \
    --form Content-Type=image/jpeg \
    --form file=PATH_TO_FILE
    ```
    
    **Example (Node.js):** Using the `post_url` and `fields` from the signed response from step one:
    
    ```js
    import fs from 'node:fs';
    import path from 'node:path';
    
    // After getting signedResponse from POST /spaces/:space_id/assets/
    const filePath = './path/to/your/asset.jpg';
    const fileBuffer = fs.readFileSync(filePath);
    const filename = path.basename(filePath);
    
    const form = new FormData();
    for (const [key, value] of Object.entries(signedResponse.fields)) {
      form.append(key, value);
    }
    form.append('file', new Blob([fileBuffer]), filename);
    
    const uploadResponse = await fetch(signedResponse.post_url, {
      method: 'POST',
      body: form,
    });
    console.log(uploadResponse);
    ```
    
3.  Finish upload
    
    Finally, finish and validate the upload using the [dedicated endpoint](/docs/api/management/assets/finish-upload). This step is optional and only applies if the first request has been made with `validate_upload=1`.
    

## Replace

The same steps apply to replacing an asset. In the first step, send the existing asset’s numeric ID in the request body under the **`id`** parameter. The second and third steps remain the same.

Example request body for replace (when calling the [get-signed-response](/docs/api/management/assets/get-signed-response) endpoint):

```json
{
  "filename": "image.jpg",
  "id": 12345678
}
```

The **`id`** must be the numeric ID of the existing asset [object](/docs/api/management/assets/the-asset-object) you want to replace.

## Pagination

-   [Previous: Update Asset](/docs/api/management/assets/update-asset)
-   [Next: Introduction](/docs/api/management/ai-style-groups)
