Sources
POST /posts takes one content source. If you send more than one, the first in this order wins:
suggestionId: accepts the idea and posts it.contentId: an accepted or rendered piece.deckwithformat: renders first, so the call returns202and astatusUrl.videoUrlorimages: your own media.
Schedule to TikTok and YouTube Shorts
curl -X POST "https://looptake.com/api/v1/posts" \
-H "Authorization: Bearer $LOOPTAKE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"contentId": "c02119cb-ed7a-40ed-87fe-c18edc1fa1a2",
"selectedAccounts": {
"tiktok": ["ff9d429b-07c5-4320-a98c-ac6e1791b828"],
"youtube": ["1c74c860-000b-4136-88a7-a17f31019346"]
},
"schedule": "scheduled",
"scheduledTime": "2026-09-01T15:00:00Z",
"timezone": "Europe/Lisbon",
"declarations": { "madeForKids": false }
}'Targets and timing
selectedAccountsmaps platform to account ids fromGET /accounts. At least one list must be non-empty.schedule:asap(after render),scheduled(atscheduledTime) ordraft(held untilPOST /posts/{id}/publish).timezoneis an IANA name. Default UTC.perPlatformsets a caption, hashtags, YouTube title or first comment per platform. Caption length is checked per platform.declarations.madeForKidsis required when a YouTube account is a target.tiktokSendToInboxsends the video to the TikTok inbox, without a caption.
Posts endpoints share a limit of 60 requests per 300 seconds.
Preview
POST /posts/preview takes the same body and returns what each account would get: caption text, YouTube title, declarations and any per-account refusal. Nothing is created or charged.
Request
curl -X POST "https://looptake.com/api/v1/posts/preview" \
-H "Authorization: Bearer $LOOPTAKE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"selectedAccounts": {"tiktok": ["ff9d429b-07c5-4320-a98c-ac6e1791b828"]},
"caption": "Your stockroom is lying to you",
"hashtags": ["retail"]
}'Statuses
GET /posts/{id} returns one target per account, each with its own status, platform post id, URL, error and analytics. Stop polling on posted, partial, failed, cancelled or draft, or when renderStatus is failed. partial means some targets posted and some did not. Or subscribe to webhooks.
Edit and cancel
PATCH /posts/{id}replaces caption, hashtags,perPlatformor declarations before the post goes out.POST /posts/{id}/reschedulemoves it. An approved post goes back to review.DELETE /posts/{id}cancels a draft, queued or scheduled post. Once publishing has started it returns409.POST /posts/{id}/publishreleases a draft. Only this call moves a draft.
CSV import
POST /posts/import takes columns caption, videoUrl, and optional scheduledTime and hashtags. All rows are checked first; one bad row imports nothing and the error lists every bad row. Rows are saved as drafts unless you send schedule: "scheduled". Use validateOnly for a dry run.
Dry run
curl -X POST "https://looptake.com/api/v1/posts/import" \
-H "Authorization: Bearer $LOOPTAKE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"csv": "caption,videoUrl,scheduledTime\nYour stockroom is lying to you,https://cdn.example/a.mp4,2026-09-02 15:00\n",
"selectedAccounts": {"tiktok": ["ff9d429b-07c5-4320-a98c-ac6e1791b828"]},
"timezone": "Europe/Lisbon",
"validateOnly": true
}'Calendar
GET /calendar?from=…&to=… groups posts by local day in the workspace timezone. Both dates are required. Media is kept until you delete it; cancelling a post keeps its media.