Set cover
Apply one candidate from Suggest covers as a cover. Video posts: the image is saved separately on YouTube, Instagram, Facebook, and each manual channel (changing one later in the composer does not change the others); YouTube / Instagram / Facebook set it via API after publishing, and manual channels include it in their kit. When TikTok is a target, its cover frame is set to that candidate's timestamp. Image posts: the image is moved to the first position (the first image is the cover).
/api/v1/posts/{postId}/coverAuthorization & guardrails
- Send
Authorization: Bearer <credential>; credentials are issued under Settings → Integrations → Long-lived credentials, see Authentication. - The credential needs scope
posts:write; the issuer's workspace role must also allow the action. - Rate limit: write tier, 10/min per credential; over the cap returns 429 with
Retry-After. - Idempotency: honoured when
Idempotency-Keyis present; optional otherwise.
Path parameters
postIdstringrequiredPost id.
Request body (application/json)
suggestionIdstringrequiredsuggestionId from Suggest covers.
candidateIdstringrequiredcandidates[].id from Suggest covers.
clientRequestIdstringoptionalIdempotency key (8–128 chars of [A-Za-z0-9_.:-]); prefer the Idempotency-Key header, which wins over the body.
Rules
- Same editable statuses as Update post: draft / rejected / scheduled; non-drafts need the publish role, and editors can only change their own drafts.
- Changing the cover changes the post, so an earlier confirmToken stops working; go through publish confirmation again.
Responses
Success is HTTP 200 with a { data, meta } envelope; examples per status are on the right (at the end of the page on narrow screens). Every error is { error: { code, message, params }, meta } — branch on the code, not the message; see Errors.
| Status | Possible codes |
|---|---|
| 400 | invalid_input |
| 401 | unauthenticated |
| 402 | plan_limit |
| 403 | forbidden / workspace_not_found |
| 404 | not_found |
| 409 | no_account / needs_reauth / replay |
| 429 | rate_limited |
| 500 | internal |
| 502 | platform_error |
| 503 | external_writes_off |
Examples
curl -X POST "https://popkit.loxily.com/api/v1/posts/pst_01J8ZK3R7QW6M2/cover" \
-H "Authorization: Bearer popkit_it_••••••••" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: acme-2026-09-21-001" \
-d '{
"suggestionId": "3f2b9c1e-6d0a-4e8b-9a7c-5b1d2e3f4a60",
"candidateId": "f03"
}'{
"data": {
"postId": "pst_01J8ZK3R7QW6M2",
"suggestionId": "3f2b9c1e-6d0a-4e8b-9a7c-5b1d2e3f4a60",
"candidateId": "f03",
"appliedAs": "cover",
"coverUrl": "https://storage.googleapis.com/socialhub-media/posts/u_01J7…/7c1e….jpg",
"tiktokCoverTimestampMs": 12000,
"deepLink": "https://popkit.loxily.com/composer?draft=pst_01J8ZK3R7QW6M2"
},
"meta": {
"requestId": "6a1d0c9e-2b7f-4e3a-8c5d-1f0e9b8a7c84"
}
}