ARTICLE AD BOX
I have gotten the signed upload url which is step one. No matter what I put in the headers for the second fetch request a 412 error is returned (see at bottom). I've become stuck at this point.
const photoFile = formData.get("photo") as File; // 1. Get signed URL const { createAsset } = await hygraphClient.request( `mutation CreateAsset($data: AssetCreateInput!) { createAsset(data: $data) { id url upload { requestPostData { url date key signature algorithm policy credential securityToken } } } }`, { data: { fileName: photoFile.name } } ); console.log("CreateAsset response:", createAsset); // 2. Upload file to the signed URL const uploadResponse = await fetch( createAsset.upload.requestPostData.url, { method: "POST", // Or PUT, depending on Hygraph's response headers: { "X-Amz-Date": createAsset.upload.requestPostData.date, "key": createAsset.upload.requestPostData.key, "X-Amz-Signature": createAsset.upload.requestPostData.signature, "X-Amz-Algorithm": createAsset.upload.requestPostData.algorithm, "policy": createAsset.upload.requestPostData.policy, "X-Amz-Credential": createAsset.upload.requestPostData.credential, "X-Amz-Security-Token": createAsset.upload.requestPostData.securityToken, }, body: photoFile, } ); console.log("Upload response:", uploadResponse); if (createAsset.id) { photoId = createAsset.id; // Publish the asset await hygraphClient.request(PublishAsset, { id: photoId }); }Here is the official documentation: https://hygraph.com/docs/api-reference/assets/uploading-assets
There is no mention of needed permissions in the docs other than a HTTP POST Request with curl where the headers I've already added were used.
Upload response: Response { status: 412, statusText: 'Precondition Failed', headers: Headers { 'x-amz-request-id': 'REJY7FA23AATVDKR', 'x-amz-id-2': '8unCNRo25luXo1jcWPt6rho5vl787feNRJ2uDLJQyJKeic0fLIlpXVEhoXb800f+W5PE3aYuiy0=', 'content-type': 'application/xml', 'transfer-encoding': 'chunked', date: 'Tue, 13 Jan 2026 22:29:36 GMT', connection: 'close', server: 'AmazonS3' }, body: ReadableStream { locked: false, state: 'readable', supportsBYOB: true }, bodyUsed: false, ok: false, redirected: false, type: 'basic', url: 'https://shared-us-west-2-assets-delivery-1b85646.s3.us-west-2.amazonaws.com/' }