Uploading assets
If you want to find out which asset system your project uses and which section of this document applies to you, click here.
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:
- Send a
createAsset
mutation passing some basic information about the asset. This also works as a nested mutation. - You can upload by file or by URL. The upload works differently depending on your choice.
- As soon as that the upload complete, the asset entry will switch from an internal
ASSET_CREATE_PENDING
state toASSET_CREATE_COMPLETE
, and the asset will be served via its URL.
#Upload by file
This is a two-step process:
- Create the asset via GraphQL mutation. This returns a URL that needs to be called to execute the upload.
- Use that pre-signed URL to upload the asset file. The asset stays pending until the file gets successfully uploaded and analysed.
Size limits for uploaded files depend on the plan. Check out our pricing page.
#Create asset via GraphQL mutation
The first step is to create the actual asset.
If you don't pass a fileName
, the system uses the file name of the file you provide - via URL or local file.
If you pass a fileName
, it overwrites the name of the file you provide. You will need to add it to data
.
Here's a sample mutation to create an asset called test.jpg
, and the JSON response:
Regarding the expiry of the requestPostData
information:
You can use the expiresAt
field for this.
If you use the requestPost
info after that date, it will fail.
#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
You must put the file
as last form entry. All other form entries must come before it.
The system also allows you to reupload a file for an existing asset entry. Click here to know more.
#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"}) {idurl}}
As this is an asynchronous process, the image may still become PENDING
until fully uploaded.
The system also allows you to reupload a file for an existing asset entry. Click here to know more.
#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.
- You must append
/upload
to your project API endpoint when uploading assets. For example,https://[region].hygraph.com/v2/[projectId]/[environment]/upload
. - You can upload assets to your project without the need of a Permanent Auth Token by adding Read and Create permissions to the Content API. This is however unsafe and not advised, as exposing the endpoint anywhere - like your website - while having any write access on the Public API, would essentially allow anyone to modify your data.
#Upload by file (Legacy)
Size limits for uploaded files depend on the plan. Check out our pricing page.
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.