API docs

Base URL https://postcache.dev · OpenAPI 3.1: /openapi.json · for agents: /llms.txt

Authentication

Every request sends Authorization: Bearer pc_live_…. Keys are issued for early access: write to hello@postcache.dev.

Upload

Send the file as the raw body and name the platform it is for. The answer is a public URL to hand to the platform API (image_url / video_url).

curl -X PUT https://postcache.dev/v1/media?ttl=86400 \
  -H "Authorization: Bearer $POSTCACHE_KEY" \
  -H "x-target: instagram.feed" \
  -H "x-filename: spring-sale.jpg" \
  --data-binary @spring-sale.jpg

Upload by URL

For files that already live somewhere public. Only public http(s) addresses are fetched; private and internal addresses are refused, also after redirects.

curl -X POST https://postcache.dev/v1/media/from-url \
  -H "Authorization: Bearer $POSTCACHE_KEY" -H "content-type: application/json" \
  -d '{"source_url": "https://example.com/reel.mp4", "target": "instagram.reels"}'

Fixing files

Add convert=crop or convert=pad (query parameter, or "convert" in the JSON body). A file that already passes is stored at once (201). A file that fails only on things conversion can fix is converted in the background:

The answer is 202 with "status": "converting". Poll GET /v1/media/{id} until status is ready (the url is set) or failed (checks says why). original_checks keeps the problems the upload had.

Dry run

dry_run=1 checks the file and stores nothing. With convert, the answer also says whether conversion could fix it (convertible).

Responses

201 { "id": "x8Kq…", "status": "ready", "url": "https://cdn.postcache.dev/m/x8Kq…/spring-sale.jpg",
      "target": "instagram.feed", "content_type": "image/jpeg", "size": 412339,
      "expires_at": "2026-10-08T12:00:00Z", "checks": { "pass": true, "problems": [], "notes": [] } }

202 { "id": "Zp3v…", "status": "converting", "target": "instagram.feed",
      "original_checks": { "pass": false, "problems": [{ "rule": "aspect", … }] },
      "status_url": "/v1/media/Zp3v…" }

422 { "error": "checks_failed", "checks": { "pass": false, "problems": [
      { "rule": "duration", "message": "Duration is 2.0 s, allowed 3–900 s.", "fix": "Trim the video." } ] } }

Other errors: 400 (bad target, ttl, convert or source URL), 401 (key), 402 quota_exceeded (the plan's uploads are used up; upgrade_url says where to upgrade), 413 (over 1 GiB), 429 budget_exceeded (the key's daily cap is reached; Retry-After counts to 00:00 UTC), 503 with Retry-After (busy).

Pay per use (no account)

Agents can pay per request instead of using a key: $0.01 per upload in USDC, through x402 (Base) or MPP (Tempo). Send the upload without Authorization; the answer is 402 with the payment challenge in WWW-Authenticate (MPP) and Payment-Required (x402). Pay and send the same request again. Payments settle through Stripe.

Plans and keys

Free has 100 uploads a month, Builder 2,000 and Studio 20,000. Dry runs are free. Manage keys, daily caps and billing at postcache.dev/dashboard.

Status and delete

GET /v1/media/{id} returns status, URL, expiry and how often the URL was fetched. DELETE /v1/media/{id} removes the file at once (204); call it after the post is published. Expired or deleted URLs answer 410; after a delete the status is deleted.

MCP

postcache is also an MCP server: https://postcache.dev/mcp (Streamable HTTP). Add it to your agent:

{
  "mcpServers": {
    "postcache": {
      "type": "http",
      "url": "https://postcache.dev/mcp",
      "headers": { "Authorization": "Bearer pc_live_…" }
    }
  }
}

Targets

TargetImagesVideo
instagram.feedJPEG, ≤ 8 MB, 4:5–1.91:1, sRGBnone (use instagram.reels)
instagram.carouselas feedas reels
instagram.reelsnoneMP4/MOV, H.264/HEVC, 4:2:0, AAC ≤ 48 kHz stereo, 23–60 fps, ≤ 1920 px wide, 0.01–10:1, ≤ 25 Mbps, 3 s–15 min, ≤ 300 MB, moov first, no edit list
instagram.storyJPEG, ≤ 8 MB, sRGBas reels, 0.1–10:1, 3–60 s, ≤ 100 MB
threadsJPEG/PNG, ≤ 8 MB, up to 10:1as reels, ≤ 100 Mbps, up to 5 min, ≤ 1 GB
facebook.pageJPEG/PNG, ≤ 10 MBMP4/MOV, H.264/HEVC, ≤ 1 GB

Limits come from Meta's developer documentation.