Skip to main content
Publish to a TikTok Shop connection that you can access in your workspace. These endpoints support tiktok_shop_video and tiktok_shop_photo.

Before you start

  • Send your organization API key in Authorization: Bearer ....
  • The key creator must remain a workspace member with access to the selected TikTok Shop connection.
  • Media preparation and new submissions require an active Pro or higher plan and publishing enabled for your workspace.
  • Video submissions use your API wallet. See current pricing. Photo submissions, reads, media preparation, and cancellation are free.
Accepted tasks continue after a plan downgrade. Losing account access or workspace membership can stop an unsent task.
Publishing returns a task with task_id and kind. Read it through /publishing/tasks/{kind}/{task_id}. The generation and cleaning /jobs endpoints do not track publishing tasks.

Find a connection and product

The response contains a data array. Select its connection_uid, then inspect the connection and its capabilities: For products, use query, source=showcase|shop, and eligibility=publishable|addable|all. The default eligibility is publishable. page_size defaults to 20 and accepts 1–100. page_token is a numeric offset. Set include_total=true when you need a total. For music, provide exactly one of query or url. Keyword searches accept search_id, page_token, region, language, and page_size (1–50, default 20). URL lookup does not accept search pagination or locale overrides. For photo destinations, pass type=category or type=collection. Only collection lookup accepts page_token. Query parameters must not be repeated.

Upload and prepare a video

Follow the Files upload flow to upload your video. Complete the multipart upload before preparing it. Publishing accepts the returned file_id, not a URL or storage path. To publish a generated video, download its result and upload the file through this flow. Replace the example file ID and connection UID with your own values:
The HTTP 200 response contains id, kind, connection_uid, and status: "prepared". Save the pm_... ID as prepared_video_id. A prepared ID belongs to one workspace, connection, and media kind. For a custom cover, upload an image and repeat this request with kind: "cover". Save its ID as prepared_cover_id. Do not send cover_uri in a submission.

Submit a video

Save a new idempotency key before submitting. Replace the connection UID, prepared media ID, and product ID below with values from the preceding steps.
The HTTP 202 response is the publishing task. Acceptance does not mean the video has been published. Save kind and task_id for polling. Use snake_case for all publishing request fields, including nested provider_options fields. Unknown options are rejected. media.prepared_video_id is required for video. You may also include media.prepared_cover_id. Do not include media.file_ids for video.

Submit a photo set

Upload each image through Files. Submit their file IDs directly; photo sets do not use /publishing/media. Send this body to POST /publishing/tasks with a fresh Idempotency-Key:
You can submit 1–35 images. Do not include prepared video or cover IDs. Photo options accept title (up to 5,000 characters), is_ai_generated, and selected_music in addition to the fields for the selected post_type: For category and collection links, include shop_link.group_id from destination discovery. Omit it for MAIN_PAGE. Only collection links accept shop_link.page_token.

Schedule publishing

timezone is required even for immediate submissions. Use an enum value from the API reference, such as EST or GMT+8. Omit schedule to submit immediately. For a scheduled submission, set schedule.at to a future Unix timestamp in milliseconds. It must be at least 60 seconds in the future and no more than 30 days in the future. Compute it when you submit; do not reuse an old timestamp.

Track and cancel tasks

Follow Retry-After when present. The API suggests 10 seconds for queued, scheduled, running, and unknown tasks. Task timestamps (created_at, schedule_time, and completed_at) use Unix milliseconds; the latter two may be null. publish_job_id may be null for older tasks. List tasks with GET /publishing/tasks?kind=tiktok_shop_video. kind is required. Optional filters include connection_uid, client_source, status, created_after_ms, and created_before_ms. Pagination uses page (default 1) and page_size (1–100, default 20). The response contains data, page, page_size, total, and has_more. Lists include authorized tasks across creation sources. Set client_source=openapi to select API-created tasks. Use client_source=unknown for tasks without a recorded source. Cancel an eligible unsent task with POST /publishing/tasks/{kind}/{task_id}/cancel. No body is required. A task that can no longer be canceled returns 409 with task_not_cancellable. Cancellation cannot remove an already published post. cost.amount_usd and cost.refunded_usd show booked wallet transactions as six-decimal USD strings. Confirmed failures and eligible cancellations refund the original charge. An unknown outcome does not trigger an automatic resend or refund.

Recover an interrupted submission

Publishing idempotency keys are scoped to your workspace across organization API keys. Repeating the same key and body returns the current original task with HTTP 202, including failed tasks. Reusing a key with a different body returns 409 with idempotency_key_reused. If submission times out or the result cannot be read, recover with the original key:
Keep the original request body. If you retry submission, use that body and the same key. Do not switch to a new key to resolve an uncertain result. Recovery returns task_not_found when it cannot find the attempt, or result_unavailable when an accepted attempt cannot currently be read.

Rate limits and errors

Publishing defaults to 120 read requests and 30 write requests per minute per workspace. Workspace-specific limits can differ. On 429, follow Retry-After before retrying. Errors use the standard error format. Common codes include plan_required, permission_denied, connection_not_found, capability_disabled, invalid_media_reference, invalid_parameter, and publishing_rejected. A 503 with service_unavailable indicates temporary admission unavailability; follow its Retry-After header.