Easily restore your project to a previous version with our new Instant One-click Backup Recovery
Hygraph
Classic Docs

Uploading assets

#Hygraph Asset Management

Our asset system uses AWS S3's pre-signed upload URLs and includes the upload action into the GraphQL API.

This process will cover the following steps:

  1. Send a createAsset mutation passing some basic information about the asset. This also works as a nested mutation.
  2. You can upload by file or by URL. The upload works differently depending on your choice.
  3. As soon as that the upload complete, the asset entry will switch from an internal ASSET_CREATE_PENDING state to ASSET_CREATE_COMPLETE, and the asset will be served via its URL.

#Upload by file

This is a two-step process:

  1. Create the asset via GraphQL mutation. This returns a URL that needs to be called to execute the upload.
  2. Use that pre-signed URL to upload the asset file. The asset stays pending until the file gets successfully uploaded and analysed.

#Create asset via GraphQL mutation

The first step is to create the actual asset.

Here's a sample mutation to create an asset called test.jpg, and the JSON response:

#Upload asset

We will use curl for this example.

Imagine we extracted the data.createAsset.upload.requestPostData subkeys into variables, and we have a file test.jpg in our current working directory:

URL="https://dev-1-assets-delivery-f78c5b5.s3.eu-central-1.amazonaws.com"
DATE="20240123T173451Z"
KEY="clr7o58jb00w701vwhpc69xda/upload/clr7o587k000j01uhul69p0rb/clr7o58ca00qi01vw7wzoguau/clrqmzdpn00id0bvucez7gnm9"
SIGNATURE="3f812cc0b05d59ee3d1efdd9dc046ed6edf595749c2763b85b923133a84e8d86"
ALGORITHM="AWS4-HMAC-SHA256"
POLICY="eyJleHBpcmF0aW9uIjoiMjAyNC0wMS0yM1QxOTo1OTo1MS45NDdaIiwiY29uZGl0aW9ucyI6W3siYnVja2V0IjoiZGV2LTEtYXNzZXRzLWRlbGl2ZXJ5LWY3OGM1YjUifSx7ImtleSI6ImNscjdvNThqYjAwdzcwMXZ3aHBjNjl4ZGEvdXBsb2FkL2NscjdvNTg3azAwMGowMXVodWw2OXAwcmIvY2xyN281OGNhMDBxaTAxdnc3d3pvZ3VhdS9jbHJxbXpkcG4wMGlkMGJ2dWNlejdnbm05In0seyJ4LWFtei1hbGdvcml0aG0iOiJBV1M0LUhNQUMtU0hBMjU2In0seyJ4LWFtei1jcmVkZW50aWFsIjoiQVNJQVZRUkUzVk1FMkJHWVZLT1AvMjAyNDAxMjMvZXUtY2VudHJhbC0xL3MzL2F3czRfcmVxdWVzdCJ9LHsieC1hbXotZGF0ZSI6IjIwMjQwMTIzVDE3MzQ1MVoifSx7IngtYW16LXNlY3VyaXR5LXRva2VuIjoiSVFvSmIzSnBaMmx1WDJWakVLci8vLy8vLy8vLy93RWFER1YxTFdObGJuUnlZV3d0TVNKSE1FVUNJRUF6SFQ2OUdEWm9CcXp5Nkw4bExDUDFEZnNBZ3FaM0phRms0M3ZvcGNGRUFpRUFrVTljUVNTSTFCRmV5TVZjTEI1QkFrVzg3NUE2M2hkWTVnNDgxcEY4QitNcTlBTUlZeEFGR2d3ek56a3hNRGd4TnpRMk1ERWlERkxzOHB2a0JHRU9aV3dSZVNyUkF4amJvVXRobDRtRUM3VHVzTHpFcXc1T1JUOUZRSStYYVVQWXZRZi9ST3ZNOExBVkFYVHQwMWZHT0JyUkVRSDRDckJLSVVtMDNtQWFPd05nQ2g1aGFlTDhmTzZvRUJ3aTFLa2ZuRWpNWmtQcVJma0krMDZhK0o0SVBYTmR0bEt6b0VVOVd4Uk9TMzEyTC8rMjBpUkpLNmNoWmhhK04zVXNJMzRYR0U0L2IzNzV0aXpsWUx0RHJYN0JiMXFIdFVNYlg3VWVUaVJaSDU4S1VwRjloK2QyWWk2bUhuL1lGcmJVaGpOcjVGL1pkL2FkdU5nOGpKU3liVkw5bTVZdWQvdlI3enMyNXdpYlpJK3BOQjFXcVZzRWtiN09EN2g1QjFlQkE5dnNMdzBKdVlFMmFnYm0xNjF0SjZVS3A5Tkd4YmVWaFM1TjQ5N2txV2MzN3pCT3ZxdWxUU1JHUW04V1QrNGx1YzZyd2VTT0lFeUxMaFowT1ZCSWM1Q0Nrc1YvaFAxT2dxeUdSNGdKTDlwa3RhUDl0encxaFhyUHJhUW1mRHhoaVgrUStaNitkSWFxalY2VGlwcVhqTk9jM2tFSFIwNmpydnlhOVFsRGxXaWd2eGRaTHkwZktzQW8vR0dBTlhlM2ZGSzhVclVObE4ySHFGeHpBYU9JNEJPMmU1VE1sUzA5MTZZTFZUN1Zxd3hHOHQ0NTlUTUFLcXpJMTJ4N2JTbHFYQ0lHUlc1anlsazhaTE1mbGRZS2t6eDN6dWNKZDYvYVN4Q1c1bE1pa2lGRjYrbW9WQW9kck1qeGhLZW42QnNRZ3ZMVW1kamFmaVROMkRERDhMK3RCanFsQVRzWGdYUmdZOUVJQzJMUXEyOU0xSGRlbmViY3I5YU5JbmFBTVFKRlpMUnl1bnM3dzk0MnhjaW1sSTYyak15RWFUczRZM3M3aTMwYVpqc1E2ampMK1hKMVJTQW5Ta2lndFJZbHVKSGFlaWJkRDMydEZDamZhY3ovZWF5eVhGcEgzekc5NHJRZUk1V0ZBWVZXRFZyWEN2WmJROG9SejV4OHN5ZFBBZWROR1VEOHYrMk5XWDc0NTBTcXdXc2Jta0dlekxoZ0pzNkxyOVhSSG5rTEljdGFoUDVoazg0Q3p3PT0ifV19"
CREDENTIAL="ASIAVQRE3VME2BGYVKOP/20240123/eu-central-1/s3/aws4_request"
SECURITY_TOKEN="IQoJb3JpZ2luX2VjEKr//////////wEaDGV1LWNlbnRyYWwtMSJHMEUCIEAzHT69GDZoBqzy6L8lLCP1DfsAgqZ3JaFk43vopcFEAiEAkU9cQSSI1BFeyMVcLB5BAkW875A63hdY5g481pF8B+Mq9AMIYxAFGgwzNzkxMDgxNzQ2MDEiDFLs8pvkBGEOZWwReSrRAxjboUthl4mEC7TusLzEqw5ORT9FQI+XaUPYvQf/ROvM8LAVAXTt01fGOBrREQH4CrBKIUm03mAaOwNgCh5haeL8fO6oEBwi1KkfnEjMZkPqRfkI+06a+J4IPXNdtlKzoEU9WxROS312L/+20iRJK6chZha+N3UsI34XGE4/b375tizlYLtDrX7Bb1qHtUMbX7UeTiRZH58KUpF9h+d2Yi6mHn/YFrbUhjNr5F/Zd/aduNg8jJSybVL9m5Yud/vR7zs25wibZI+pNB1WqVsEkb7OD7h5B1eBA9vsLw0JuYE2agbm161tJ6UKp9NGxbeVhS5N497kqWc37zBOvqulTSRGQm8WT+4luc6rweSOIEyLLhZ0OVBIc5CCksV/hP1OgqyGR4gJL9pktaP9tzw1hXrPraQmfDxhiX+Q+Z6+dIaqjV6TipqXjNOc3kEHR06jrvya9QlDlWigvxdZLy0fKsAo/GGANXe3fFK8UrUNlN2HqFxzAaOI4BO2e5TMlS0916YLVT7VqwxG8t459TMAKqzI12x7bSlqXCIGRW5jylk8ZLMfldYKkzx3zucJd6/aSxCW5lMikiFF6+moVAodrMjxhKen6BsQgvLUmdjafiTN2DDD8L+tBjqlATsXgXRgY9EIC2LQq29M1Hdenebcr9aNInaAMQJFZLRyuns7w942xcimlI62jMyEaTs4Y3s7i30aZjsQ6jjL+XJ1RSAnSkigtRYluJHaeibdD32tFCjfacz/eayyXFpH3zG94rQeI5WFAYVWDVrXCvZbQ8oRz5x8sydPAedNGUD8v+2NWX7450SqwWsbmkGezLhgJs6Lr9XRHnkLIctahP5hk84Czw=="
curl --request POST \
--url $URL
--form X-Amz-Date=$DATE
--form key=$KEY
--form X-Amz-Signature=$SIGNATURE
--form X-Amz-Algorithm=$ALGORITHM
--form policy=$POLICY
--form X-Amz-Credential=$CREDENTIAL
--form X-Amz-Security-Token=$SECURITY_TOKEN
--form file=@./test.jpg

#Upload by remote URL

You can upload assets by remote URL in the GraphQL API by passing the URL of an asset hosted somewhere publicly accessible in the createAsset mutation from step 1.

mutation test {
createAsset(
data: {
uploadUrl:"https://images.unsplash.com/photo-1682687218147-9806132dc697"
}
) {
id
url
}
}

#Legacy asset system

Hygraph supports uploading assets via HTTP. You'll need a Permanent Auth Token with Mutations API access enabled to upload by file, or URL.

Assets are treated just like any other content entry, so they are automatically bound to the environment, and authorization settings of your project.

#Upload by file (Legacy)

Here's also a standard JavaScript example:

const HYGRAPH_URL = '';
const HYGRAPH_ASSET_TOKEN = '';
async function upload() {
const input = document.getElementById('fileUpload');
const file = input.files[0];
const form = new FormData();
form.append('fileUpload', file);
// It is not recommended to use the HYGRAPH_ASSET_TOKEN in the Front-End.
// In this example we're using it, but in a real application you should
// use a backend to upload the file and use the HYGRAPH_ASSET_TOKEN there.
const response = await fetch(`${HYGRAPH_URL}/upload`, {
method: 'POST',
headers: {
Authorization: `Bearer ${HYGRAPH_ASSET_TOKEN}`,
},
body: form,
});
const data = await response.json();
console.log(JSON.stringify(data, null, 2));
}

#Upload by remote URL (Legacy)

You can also upload files by providing a remote URL, instead of a file.