The DropInBlog API has no separate upload endpoint. You give us images by URL in two places when you create or update a post: the featured_image field, and <img> tags inside content. We download each image, store it in your blog's media library on our CDN, and point the post at our copy. Once that's done you don't need to keep hosting the original.
How it works
- You call
POST /v2/blog/{blog_id}/postsorPATCH /v2/blog/{blog_id}/posts/{id}with image URLs. - We save the post and respond right away.
- In the background we fetch each image, store it on our CDN and swap the URLs in the post.
- We then process each image into responsive widths and a ThumbHash placeholder.
Steps 3 and 4 happen after we respond. So the response to your create or update call still shows your original image URLs in content, and featuredImage is null on a new post (or the previous image on an update). Retrieve the post again a little later to read the final URLs.
Requirements for image URLs
- Absolute
httporhttpsURL - Publicly reachable without signing in. Private network and localhost addresses are refused.
- 20 MB or less
- Responds within 15 seconds. We follow up to 5 redirects.
- JPG, PNG, GIF, WebP, AVIF or SVG
- If your host blocks bots, allow our user agent:
DropInBlog/1.0 (+https://dropinblog.com)
Pre-signed URLs (S3, Google Cloud Storage and similar) work as long as they're still valid when we fetch them. Give them at least a few minutes before they expire.
File names and duplicates
We name the stored file from the Content-Disposition header if there is one, then from the file name in the URL, then from the post's slug. Names are lowercased and slugged, for example Spring Garden.JPG is stored as spring-garden.jpg.
Sending the same image again (same name and identical bytes) reuses the stored file and keeps its URL, so re-running an import doesn't fill the media library with copies. A different image with a name that's already taken is stored as name-2.jpg, name-3.jpg and so on.
Updating images
- Send
featured_imagein aPATCHto replace the featured image. - Leave
featured_imageout to keep the current one. - Images in
contentare only scanned when you sendcontent. APATCHthat changes only the title or SEO fields doesn't touch them.
Image fields in responses
| Field | What it holds |
|---|---|
featuredImage | URL of the featured image at your blog's display width |
featuredImageWidth, featuredImageHeight | Size of the original image in pixels, or null until it's measured |
featuredImageVariants | Array of { "width", "url" }, one for each width we serve, for building your own srcset |
featuredImageThumbhash | Base64 ThumbHash for a blurred placeholder while the image loads. null for GIFs, transparent images and images not processed yet. |
featuredImageWebm, featuredImageMp4 | Video versions of an animated GIF featured image, otherwise null |
Images inside content come back with srcset, sizes and loading="lazy" already added.
Treat image URLs as opaque. Their format changes once processing finishes, so read them from the API rather than building or parsing them.
Example after processing:
{
"featuredImage": "https://dropinblog.net/img/k3j9x2ab/1000/spring-garden",
"featuredImageWidth": 2400,
"featuredImageHeight": 1600,
"featuredImageThumbhash": "3OcRJYB4d3h/iIeHeEh3eIhw+j2w",
"featuredImageVariants": [
{ "width": 320, "url": "https://dropinblog.net/img/k3j9x2ab/320/spring-garden" },
{ "width": 700, "url": "https://dropinblog.net/img/k3j9x2ab/700/spring-garden" },
{ "width": 1000, "url": "https://dropinblog.net/img/k3j9x2ab/1000/spring-garden" }
],
"featuredImageWebm": null,
"featuredImageMp4": null
}
The MCP server's create and update post tools handle images the same way.