Skip to content

Upload and Replace Assets

Uploading assets to Storyblok is a three-step process.

  1. Get signed response

    Use the get signed response endpoint 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):

    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:

    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. This step is optional and only applies if the first request has been made with validate_upload=1.

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 endpoint):

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

The id must be the numeric ID of the existing asset object you want to replace.

Was this page helpful?

What went wrong?

This site uses reCAPTCHA and Google's Privacy Policy. Terms of Service apply.