Search Storyblok's Documentation
  1. Upload And Replace Assets

Upload And Replace Assets

Uploading assets in Storyblok is a three-step process. First, you need to sign the asset you want to upload. Then you need to post the image as form data to our Amazon S3 bucket. Lastly, you need to send another request to finalize the process and let Storyblok retrieve the MIME type and the content length for your asset.

Uploaded files will have parameterized names; Every dot "." (except the last one) will be replaced with an underscore "_".

Following is the step by step process explained -

  1. 1

    Getting a Singed Response Object

    Start by requesting a Singed Response Object. You need to send this request with the filename and size. Also, you need to pass a key and value pair "validate_upload":"1" to the request.

    Request
    curl "https://mapi.storyblok.com/v1/spaces/656/assets/" \
      -X POST \
      -H "Content-Type: application/json" \
      -H "Authorization: YOUR_OAUTH_TOKEN" \
      -d " {\"filename\": \"your_file.jpg\",\"size\": \"400X500\",\"asset_folder_id\" : 123 // with asset folder, Optional\"validate_upload\": 1 }"
    Request
    // Using the Universal JavaScript Client:
    // https://github.com/storyblok/storyblok-js-client
    Storyblok.post('/spaces/656/assets/',  {
      "filename": "your_file.jpg",
      "size": "400X500",
      "asset_folder_id" : 123 // with asset folder, Optional
      "validate_upload": 1
     }
    )
      .then(response => {
        console.log(response)
      }).catch(error => { 
        console.log(error)
      })
    Request
    $client = new \Storyblok\ManagementClient('YOUR_OAUTH_TOKEN');
    
    $payload =  [
      "filename" =>  "your_file.jpg",
      "size" =>  "400X500",
      "asset_folder_id"  =>  123 // with asset folder, Optional
      "validate_upload" =>  1
     ]
    ;
    
    $client->post('/spaces/656/assets/', $payload)->getBody();
    Request
    require 'storyblok'
    client = Storyblok::Client.new(oauth_token: 'YOUR_OAUTH_TOKEN')
    
    payload =  {
      "filename" =>  "your_file.jpg",
      "size" =>  "400X500",
      "asset_folder_id"  =>  123 // with asset folder, Optional
      "validate_upload" =>  1
     }
    
    
    client.post('/spaces/656/assets/', payload)
    Request
    HttpResponse<String> response = Unirest.post("https://mapi.storyblok.com/v1/spaces/656/assets/")
      .header("Content-Type", "application/json")
      .header("Authorization", "YOUR_OAUTH_TOKEN")
      .body(" {\"filename\": \"your_file.jpg\",\"size\": \"400X500\",\"asset_folder_id\" : 123 // with asset folder, Optional\"validate_upload\": 1 }")
      .asString();
    Request
    var client = new RestClient("https://mapi.storyblok.com/v1/spaces/656/assets/");
    var request = new RestRequest(Method.POST);
    
    request.AddHeader("Content-Type", "application/json");
    request.AddHeader("Authorization", "YOUR_OAUTH_TOKEN");
    request.AddParameter("application/json", " {\"filename\": \"your_file.jpg\",\"size\": \"400X500\",\"asset_folder_id\" : 123 // with asset folder, Optional\"validate_upload\": 1 }", ParameterType.RequestBody);
    IRestResponse response = client.Execute(request);
    Request
    import Foundation
    
    let headers = [
      "Content-Type": "application/json",
      "Authorization": "YOUR_OAUTH_TOKEN"
    ]
    
    let postData = NSData(data: " {\"filename\": \"your_file.jpg\",\"size\": \"400X500\",\"asset_folder_id\" : 123 // with asset folder, Optional\"validate_upload\": 1 }".data(using: String.Encoding.utf8)!)
    let request = NSMutableURLRequest(url: NSURL(string: "https://mapi.storyblok.com/v1/spaces/656/assets/")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
    
    request.method = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData as Data
    
    let session = URLSession.shared
    let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
      if (error != nil) {
        print(error)
      } else {
        let httpResponse = response as? HTTPURLResponse
        print(httpResponse)
      }
    })
    
    dataTask.resume()
    Request
    import requests
    
    url = "https://mapi.storyblok.com/v1/spaces/656/assets/"
    
    querystring = {}
    
    payload = " {\"filename\": \"your_file.jpg\",\"size\": \"400X500\",\"asset_folder_id\" : 123 // with asset folder, Optional\"validate_upload\": 1 }"
    headers = {
      'Content-Type': "application/json",
      'Authorization': "YOUR_OAUTH_TOKEN"
    }
    
    response = requests.request("POST", url, data=payload, headers=headers, params=querystring)
    
    print(response.text)
  2. 2

    Use the received signed response object to upload your file

    The following example is with Node.js

    Uploading File
    const FormData = require('form-data')
    const fs = require('fs')
    
    const file = '/path_to/your_file.jpg'
    const fileUpload = (signed_response_object, success, failed) => {
      let form = new FormData()
      // apply all fields from the signed response object to the second request
      for (let key in signed_response_object.fields) {
        form.append(key, signed_response_object.fields[key])
      }
      // also append the file read stream
      form.append('file', fs.createReadStream(file))
      // submit your form
      form.submit(signed_response_object.post_url, (err, res) => {
        if (err) throw err
        // the third step will be added here
      })
    }
  3. 3

    Finalize the process

    In the end, a GET request has to be made to spaces/:space_id/assets/:singned_response_object_id/finish_upload

    The final process has to be done when the form submission in the 2nd step is successful.

    Finalizing the process
    Storyblok.get(
      "spaces/606/assets/" + signed_response_object.id + "/finish_upload"
    )
      .then((response) => {
        console.log(
          "https://a.storyblok.com/" +
            signed_response_object.fields.key +
            " uploaded!"
        );
      })
      .catch((error) => {
        throw error;
      });

Here you can find an example using Node.js on Github.

Replacing an asset

Replacing an asset is also done with the same steps. Though in the first step, the asset ID and filename should be sent with the request in the body. The second and third step remain the same.

Request
curl "https://mapi.storyblok.com/v1/spaces/656/assets/" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: YOUR_OAUTH_TOKEN" \
  -d "{\"filename\": \"image_name.jpg\",\"id\": 123123,\"validate_upload\": 1}"
Request
// Using the Universal JavaScript Client:
// https://github.com/storyblok/storyblok-js-client
Storyblok.post('/spaces/656/assets/', {
    "filename": "image_name.jpg",
    "id": 123123,
"validate_upload": 1
})
  .then(response => {
    console.log(response)
  }).catch(error => { 
    console.log(error)
  })
Request
$client = new \Storyblok\ManagementClient('YOUR_OAUTH_TOKEN');

$payload = [
    "filename" =>  "image_name.jpg",
    "id" =>  123123,
"validate_upload" =>  1
];

$client->post('/spaces/656/assets/', $payload)->getBody();
Request
require 'storyblok'
client = Storyblok::Client.new(oauth_token: 'YOUR_OAUTH_TOKEN')

payload = {
    "filename" =>  "image_name.jpg",
    "id" =>  123123,
"validate_upload" =>  1
}

client.post('/spaces/656/assets/', payload)
Request
HttpResponse<String> response = Unirest.post("https://mapi.storyblok.com/v1/spaces/656/assets/")
  .header("Content-Type", "application/json")
  .header("Authorization", "YOUR_OAUTH_TOKEN")
  .body("{\"filename\": \"image_name.jpg\",\"id\": 123123,\"validate_upload\": 1}")
  .asString();
Request
var client = new RestClient("https://mapi.storyblok.com/v1/spaces/656/assets/");
var request = new RestRequest(Method.POST);

request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "YOUR_OAUTH_TOKEN");
request.AddParameter("application/json", "{\"filename\": \"image_name.jpg\",\"id\": 123123,\"validate_upload\": 1}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Request
import Foundation

let headers = [
  "Content-Type": "application/json",
  "Authorization": "YOUR_OAUTH_TOKEN"
]

let postData = NSData(data: "{\"filename\": \"image_name.jpg\",\"id\": 123123,\"validate_upload\": 1}".data(using: String.Encoding.utf8)!)
let request = NSMutableURLRequest(url: NSURL(string: "https://mapi.storyblok.com/v1/spaces/656/assets/")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)

request.method = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
Request
import requests

url = "https://mapi.storyblok.com/v1/spaces/656/assets/"

querystring = {}

payload = "{\"filename\": \"image_name.jpg\",\"id\": 123123,\"validate_upload\": 1}"
headers = {
  'Content-Type': "application/json",
  'Authorization': "YOUR_OAUTH_TOKEN"
}

response = requests.request("POST", url, data=payload, headers=headers, params=querystring)

print(response.text)