Docs

Media Uploads

Add images, videos and PDFs to posts, by URL import or direct upload.

Diese Seite gibt es noch nicht auf Deutsch, deshalb siehst du sie auf Englisch.

Media goes in two steps: add the file with POST /media, then pass its id in mediaIds when you create or update a post.

The Node.js and Python examples use the SDKs, with a client created as shown there.

Import from a URL

The simplest way, and the right one for agents and scripts that already have a link. FeedHorizon downloads the file and answers once it is stored.

curl -X POST https://feedhorizon.com/api/v1/media \
  -H "Authorization: Bearer fh_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/launch.jpg" }'
{
  "data": {
    "id": "med_0193f…",
    "url": "https://…/media/0193f….jpg",
    "filename": "launch.jpg",
    "mimeType": "image/jpeg",
    "sizeBytes": 245760,
    "createdAt": "2026-11-04T14:00:00.000Z",
    "upload": null
  }
}

The URL must be public https and the file at most 100 MB. The type comes from the Content-Type the server sends.

Upload directly

For files on your machine and anything over 100 MB (up to 5 GB). Announce the file, then PUT the bytes to the returned link. The link is valid for two hours and needs no API key.

curl -X POST https://feedhorizon.com/api/v1/media \
  -H "Authorization: Bearer fh_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "filename": "teaser.mp4", "mimeType": "video/mp4", "sizeBytes": 48211337 }'

# then, with upload.url from the answer:
curl -X PUT "UPLOAD_URL" -H "Content-Type: video/mp4" --data-binary @teaser.mp4

Use media in a post

{
  "profileId": "YOUR_PROFILE_ID",
  "content": "The teaser is out",
  "platforms": ["instagram", "linkedin"],
  "mediaIds": ["med_0193f…"],
  "addToQueue": true
}

Files appear in the post in the order of mediaIds. On update, mediaIds replaces the media of the post, and [] removes it.

Before the post is stored, each platform's rules are checked: supported types and how many files it takes (see GET /platforms). Instagram needs at least one image or video. A file that was announced but never uploaded answers 400 media_not_uploaded. Use POST /posts/validate to see all problems before you create the post.

Supported types

POST /media stores any of these files:

TypeMIME types
Imagesimage/jpeg, image/png, image/gif, image/webp
Videovideo/mp4, video/quicktime, video/webm
Documentsapplication/pdf

Which of them a post may use, how many and how large, depends on the platform. A file a platform does not take fails the post with media_type_unsupported. Platform support has the table for every platform, generated from the same rules the API checks, and GET /platforms returns them as data.

Errors

CodeCause
invalid_urlNot a valid https URL, a URL with credentials, or a URL that points to a private network
media_fetch_failedThe URL could not be resolved or fetched, or answered with an error status
media_too_largeAn import over 100 MB, or an upload over 5 GB
media_not_found (on posts)A mediaIds entry does not exist in your organization
duplicate_media (on posts)The same id appears twice in mediaIds
media_not_uploaded (on posts)The file was announced but its bytes never arrived
media_in_use (409)DELETE /media/{id} on a file a post still uses

Manage files

  • GET /media lists your files, newest first.
  • GET /media/{id} returns one file.
  • DELETE /media/{id} deletes a file that no post uses. Files still in a post answer 409 media_in_use.

Media needs the posts:write scope to add and delete, posts:read to list.