Posts

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).

POST/api/v1/posts/{postId}/cover
posts:writewrite tierIdempotency-Key optional

Authorization & 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-Key is present; optional otherwise.

Path parameters

postIdstringrequired

Post id.

Request body (application/json)

suggestionIdstringrequired

suggestionId from Suggest covers.

candidateIdstringrequired

candidates[].id from Suggest covers.

clientRequestIdstringoptional

Idempotency 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.

StatusPossible codes
400invalid_input
401unauthenticated
402plan_limit
403forbidden / workspace_not_found
404not_found
409no_account / needs_reauth / replay
429rate_limited
500internal
502platform_error
503external_writes_off

Examples

Request
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"
}'
Response
Video post
{
  "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"
  }
}