Use CurlyFlies with Make.com

One HTTP module.
A URL the crawler fetches.

Your image-generation module returns a signed URL that expires in about an hour. Add one HTTP module before your Instagram or Buffer step and map a stable public URL instead — one that serves raw bytes for as long as your scenario’s schedule needs.

The recipe.

One HTTP → Make a request module, configured once. No custom app, no connection wizard.

STEP 01

Add an HTTP “Make a request” module after your generation module

Place it right after the module that produces the image — OpenAI (GPT Image), Replicate, or an HTTP call to Seedream / Nano Banana. Configure:

SettingValue
MethodPOST
URLhttps://curlyflies.com/v1/upload-url
Headers (item 1)Name: Authorization  ·  Value: Bearer curly_live_...
Body typeRaw
Content typeJSON (application/json)
Parse responseYes — so the output fields are mappable
// Request content — map the image URL from the previous module
{
  "url": "{{1.image_url}}",
  "ttl_seconds": 604800
}
STEP 02

CurlyFlies fetches the file server-side and returns a public URL

No binary flows through your scenario — CurlyFlies downloads the source URL while it’s still valid and re-hosts the bytes. With Parse response on, the module outputs:

{
  "file_id": "x7k2p9",
  "url": "https://curlyflies.com/f/x7k2p9.png",
  "expires_at": "2026-06-19T09:41:00Z",
  "size_bytes": 204800,
  "content_type": "image/png",
  "delete_token": "dt_abc123"
}
STEP 03

Map url into your Instagram or Buffer module

In the next module — Instagram for Business → Create a Photo Post, a Buffer module, or a raw Graph API HTTP call — click the media/photo URL field and map the Data → url output from the CurlyFlies module. The crawler fetches it, gets 200 + image/png + raw bytes, and accepts the post. Keep ttl_seconds longer than your furthest scheduled slot, and use expires_at from the output if you store URLs for later.

Free plan, honestly: 100 uploads/month, 5MB max per file, and a fixed 24-hour TTL — fine for testing and same-day publishing. Scenarios that schedule posts more than a day out need a paid plan: Builder gives TTLs up to 30 days, Pro 60, Scale 90. Plans →

Where it sits in the scenario.

One module between generation and publishing. Everything else in the scenario stays exactly as it is.

GENERATE

GPT Image / Nano Banana / Seedream / Replicate
→ signed URL, dies in ~1h

CURLYFLIES

HTTP “Make a request” module
POST /v1/upload-url → stable public URL

PUBLISH

Instagram for Business / Buffer / Graph API
photo URL = mapped url

This is the failure it fixes: generation APIs hand back temporary signed URLs (Azure blob links with se= expiry, S3 presigned URLs). Scenario runs fast? Works. Add a sleep, a queue, a retry, or schedule the post for Thursday? The URL is dead when Instagram’s crawler fetches it — error 9004, “media fetch failed.” Re-host immediately after generation with a TTL longer than the schedule, and the intermittent failures disappear. Full error-9004 guide →

Frequently asked questions.

How do I get a public URL for a file in Make.com?

One HTTP Make a request module: POST https://curlyflies.com/v1/upload-url, an Authorization: Bearer curly_live_... header, raw JSON body with the source url and a ttl_seconds. Turn on Parse response and map the returned url into any later module.

Why does my Make.com Instagram scenario fail with error 9004?

Almost always an expired or non-public media URL. Generation APIs return signed URLs that die within roughly an hour, and Drive/Dropbox links serve HTML viewer pages instead of the file. Instagram’s crawler fetches your media URL itself, anonymously — if it can’t get raw bytes, you get 9004. Troubleshooting guide →

What TTL should I set for scheduled posts?

Longer than your furthest-out slot, plus margin. A weekly calendar → "ttl_seconds": 604800 (7 days). You can also send an absolute expires_at datetime instead, which matches how schedulers think. Free plan TTL is fixed at 24h; longer TTLs need Builder (30d), Pro (60d), or Scale (90d).

Can Make.com upload binary data directly instead of a URL?

Yes. Use POST https://curlyflies.com/v1/upload with body type Multipart/form-data and map the binary data into a field named file. Same auth header, same response shape. upload-url is usually simpler — and cheaper on Make operations — because the bytes never pass through your scenario.

Why not just point Instagram at a Drive/Dropbox link or S3?

Drive and Dropbox share links serve HTML viewer pages, which fail crawler validation outright. S3 works after you configure buckets, public-read policies, and Content-Type metadata — roughly 45 minutes of AWS setup. CurlyFlies is one module, and files delete themselves after the TTL. See the full comparison →

Test it before you build the scenario.

Same request your HTTP module will make — try it from your terminal first.

$ curl -X POST https://curlyflies.com/v1/upload-url \
    -H "Authorization: Bearer $CURLY_KEY" \
    -H "Content-Type: application/json" \
    -d '{"url": "https://...signed-url...", "ttl_seconds": 604800}'

→ { "url": "https://curlyflies.com/f/x7k2p9.png",
    "expires_at": "2026-06-19T09:41:00Z" }