Uploading an image as an asset from a URL and using createIfNotExists and createOrReplace in the Sanity API.
The issue with your curl command is that you're passing a URL string to --data-binary instead of actual image binary data. The --data-binary parameter expects file contents, not a URL.
When you use --data-binary "<https://dl.airtable.com/.attachments/image.jpg>", curl is sending that literal URL string as the request body. Sanity's API tries to parse it as image data and fails with "Invalid image, could not read metadata."
To upload an image from a URL to Sanity, you need to download it first, then upload the binary data:
Option 1: Two-step process
# Download the image
curl -o temp-image.jpg "https://dl.airtable.com/.attachments/image.jpg"
# Upload to Sanity (note the @ symbol before filename)
curl -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: image/jpeg" \
--data-binary "@temp-image.jpg" \
"https://YOUR_PROJECT_ID.api.sanity.io/v2024-06-24/assets/images/YOUR_DATASET"Option 2: Single piped command
curl "https://dl.airtable.com/.attachments/image.jpg" | \
curl -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: image/jpeg" \
--data-binary @- \
"https://YOUR_PROJECT_ID.api.sanity.io/v2024-06-24/assets/images/YOUR_DATASET"The key differences:
- Use
@filenameto read from a file (the@tells curl to read file contents) - Use
@-to read from stdin when piping - Include your authentication token in the Authorization header
- Replace placeholders with your actual project ID and dataset name
According to the Assets API documentation, you can also add query parameters for metadata:
curl "https://dl.airtable.com/.attachments/image.jpg" | \
curl -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: image/jpeg" \
--data-binary @- \
"https://YOUR_PROJECT_ID.api.sanity.io/v2024-06-24/assets/images/YOUR_DATASET?filename=my-image.jpg&title=My%20Image"The API will return a sanity.imageAsset document containing the image metadata and CDN URL where it's hosted.
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.