OpenAPI reference · Media
Set a post's media (full-state)
/posts/{postId}/mediaReplaces the post's media in one write — read media on the post
first and resend the entries you are keeping, or they are gone.
Library images resolve to durable S3 keys server-side, so a post
never depends on an expiring CDN URL; assets without a stored
original are rejected with unprocessable.
source: "key" takes a stored file key — one the post already
carries. A media-library id (img_…), an upload handle
(upl_…) or a displayUrl is rejected with unprocessable
naming the branch that accepts it, because the publish step
classifies the key by extension and cannot use any of them: an
unclassifiable key used to be stored happily and then fail on
the publish cron, hours later.
A post the dashboard gave a LinkedIn poll refuses media with
conflict and is left unchanged: a post publishes media or a
poll, never both. Clearing media (kind: "none") is not refused.
The response echoes the post's resulting media. Requires
posts:write AND media:read.
Authorization
AuthorizationstringrequiredBearer token in the Authorization header.
Pass
Authorization: Bearer scripe_sk_live_<...>(orscripe_sk_test_<...>for test keys) on every request. Keys are scoped to a single workspace and can be revoked from the Scripe dashboard.The same header also accepts an OAuth 2.1 access token (
scripe_oat_*); both credentials share one scope vocabulary and every operation below documents the scope it requires. An API key can hold every scope named on this surface exceptwebhooks:manage, which is grantable to OAuth tokens only today — the webhook-endpoint operations answer403 scope_missingto every API key. Operations that name no scope accept any valid token of the workspace.
Path parameters
postIdstringrequired
Header parameters
Scripe-Api-VersionstringPin the API version. Format
YYYY-MM-DD. Omit to receive the currently rolling default. Unknown versions return400 version_unsupported.
Request bodyapplication/json
mediaobject | object | object | objectrequiredDiscriminated on
kind— images (from libraryimg_…ids or upload keys), video, document (PDF), or none to clear.
Responses
- 200
Media set.
- 400
Malformed request (bad cursor, bad limit, etc.).
- 401
Missing, malformed, expired, or revoked API key.
- 403
Plan not eligible, scope missing, or workspace mismatch.
- 404
Resource not found in this workspace.
- 409
The post carries a LinkedIn poll, and a post publishes either media or a poll, never both. Nothing is written; remove the poll in the Scripe dashboard first. See
conflict. - 422
Body shape was JSON but failed validation (
unprocessable). - 429
Sliding-window rate limit exceeded.
Example request
curl --request PATCH \
--url 'https://api.scripe.io/v1/posts/{postId}/media' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"media": {
"kind": "images",
"images": [
{
"source": "key",
"key": null,
"alt": null,
"name": null
}
]
}
}'Example response (200)
{
"data": {
"postId": "string",
"kind": "images",
"media": {}
}
}