Images

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

  1. You call POST /v2/blog/{blog_id}/posts or PATCH /v2/blog/{blog_id}/posts/{id} with image URLs.
  2. We save the post and respond right away.
  3. In the background we fetch each image, store it on our CDN and swap the URLs in the post.
  4. 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 http or https URL
  • 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_image in a PATCH to replace the featured image.
  • Leave featured_image out to keep the current one.
  • Images in content are only scanned when you send content. A PATCH that changes only the title or SEO fields doesn't touch them.

Image fields in responses

FieldWhat it holds
featuredImageURL of the featured image at your blog's display width
featuredImageWidth, featuredImageHeightSize of the original image in pixels, or null until it's measured
featuredImageVariantsArray of { "width", "url" }, one for each width we serve, for building your own srcset
featuredImageThumbhashBase64 ThumbHash for a blurred placeholder while the image loads. null for GIFs, transparent images and images not processed yet.
featuredImageWebm, featuredImageMp4Video 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.