{"openapi":"3.1.0","info":{"title":"Agentic Posting API","version":"2026-08-09","description":"TikTok-only publishing API for agents. This document is the public agent-publishing and browser-review contract; website account administration and signed provider-webhook handlers are internal integration surfaces rather than agent operations. Direct Post is always a two-step prepare and confirm workflow; the confirmation expires and requires a separate creator response. Agent confirmation uses a workspace API key. Browser confirmation requires both the intent-scoped review token and a Clerk session for a member of the owning workspace.","license":{"name":"Proprietary","url":"https://agenticposting.com/terms.html"}},"servers":[{"url":"https://api.agenticposting.com"}],"tags":[{"name":"Discovery","description":"Resolve the current Agentic Posting contract and authorized workspace context."},{"name":"Media","description":"Reserve and fill short-lived, integrity-checked TikTok media upload slots."},{"name":"Publishing","description":"Create TikTok drafts or immutable, separately confirmed Direct Post intents."},{"name":"Status","description":"Read or refresh the existing TikTok publishing job without creating a replacement."}],"paths":{"/v1/capabilities":{"get":{"operationId":"get_agentic_posting_capabilities","tags":["Discovery"],"summary":"Discover current product and provider capabilities","security":[],"responses":{"200":{"description":"Machine-readable capability contract","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Capabilities"}}}},"429":{"$ref":"#/components/responses/ApiError"},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}},"/v1/context":{"get":{"operationId":"get_agent_context","tags":["Discovery"],"summary":"Resolve the API key's workspace, TikTok account, subscription, and usage","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Agent setup context","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentContext"}}}},"401":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}},"/v1/uploads":{"post":{"operationId":"create_tiktok_upload_slots","tags":["Media"],"summary":"Reserve short-lived media upload slots","description":"Reserve exactly one MP4 video or between 1 and 35 JPEG/WebP photos. A workspace may have at most 70 unexpired active assets and 1,000,000,000 active bytes across pending, uploading, and ready assets.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadReservationRequest"}}}},"responses":{"200":{"description":"Upload URLs and asset ids","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadReservationResponse"}}}},"400":{"$ref":"#/components/responses/ApiError"},"401":{"$ref":"#/components/responses/ApiError"},"402":{"$ref":"#/components/responses/ApiError"},"403":{"$ref":"#/components/responses/ApiError"},"409":{"description":"Workspace active-media capacity is exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}},"/v1/uploads/{assetId}/content":{"put":{"operationId":"upload_tiktok_media_bytes","tags":["Media"],"summary":"Stream media into a reserved upload slot","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"assetId","in":"path","required":true,"schema":{"type":"string"}},{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}},{"name":"Content-Length","in":"header","required":true,"description":"Exact reserved byte length.","schema":{"type":"integer","minimum":1,"maximum":50000000}}],"requestBody":{"required":true,"content":{"video/mp4":{"schema":{"type":"string","contentEncoding":"binary"}},"image/jpeg":{"schema":{"type":"string","contentEncoding":"binary"}},"image/webp":{"schema":{"type":"string","contentEncoding":"binary"}}}},"responses":{"200":{"description":"Upload complete","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadComplete"}}}},"400":{"$ref":"#/components/responses/ApiError"},"401":{"$ref":"#/components/responses/ApiError"},"402":{"$ref":"#/components/responses/ApiError"},"403":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"409":{"$ref":"#/components/responses/ApiError"},"410":{"$ref":"#/components/responses/ApiError"},"411":{"$ref":"#/components/responses/ApiError"},"413":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}},"/v1/posts":{"post":{"operationId":"upload_tiktok_draft","tags":["Publishing"],"summary":"Request TikTok inbox delivery for uploaded media","description":"A successful initialization means TikTok accepted the inbox-share request, not that delivery is complete. The creator waits for TikTok's inbox notification, then finishes caption, settings, and publishing in TikTok. An exact idempotent replay returns the stored job without a second TikTok publish initialization or usage reservation and remains recoverable after entitlement ends. A racing retry may repeat a safe creator-info metadata read before it observes the winning D1 attempt. The same key with a different account, media type, or ordered asset list is rejected. TikTok limits pending inbox shares independently of the monthly Agentic Posting allowance.","security":[{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftRequest"}}}},"responses":{"200":{"description":"Newly TikTok-accepted initialization or the exact stored job recovered by an idempotent retry. Inspect status and publishId; a failed or submission_unknown stored job is not proof of acceptance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishJobResult"}}}},"400":{"$ref":"#/components/responses/ApiError"},"401":{"$ref":"#/components/responses/ApiError"},"402":{"$ref":"#/components/responses/ApiError"},"403":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"409":{"description":"The Idempotency-Key was already bound to a different draft request, or an atomic attempt found that the selected inputs changed before dispatch","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"410":{"description":"Direct Post attempted through the deprecated one-call route","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"},"502":{"description":"TikTok rejected initialization or its outcome is ambiguous. Recover the stored job by repeating the identical request with the same Idempotency-Key before deciding what to do.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}},"/v1/post-intents":{"post":{"operationId":"prepare_tiktok_post","tags":["Publishing"],"summary":"Prepare an immutable, expiring TikTok Direct Post intent","description":"Returns the complete creator-facing summary, media previews, content hash, confirmation phrase, and browser review URL. Do not call confirmation until the creator has seen all of them and replies separately.","security":[{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostIntentRequest"}}}},"responses":{"200":{"description":"Existing identical post intent recovered by an idempotent retry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostIntent"}}}},"201":{"description":"New post intent awaiting creator confirmation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostIntent"}}}},"400":{"$ref":"#/components/responses/ApiError"},"401":{"$ref":"#/components/responses/ApiError"},"402":{"$ref":"#/components/responses/ApiError"},"403":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"409":{"description":"The Idempotency-Key was already bound to different immutable intent content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"},"502":{"description":"TikTok creator identity or another required provider response is unavailable; no confirmable intent is created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}},"/v1/post-intents/{postIntentId}":{"get":{"operationId":"get_tiktok_post_intent","tags":["Publishing"],"summary":"Read the current immutable TikTok post intent","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"postIntentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current intent state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostIntent"}}}},"401":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}},"/v1/post-intents/{postIntentId}/review":{"get":{"operationId":"review_tiktok_post_intent","tags":["Publishing"],"summary":"Read an intent through its browser-review capability","description":"The review token alone may read an active intent. Once the intent is terminal or expired, the response is deliberately reduced to postIntentId, status, and expiresAt. Confirmation is a separate request and additionally requires a Clerk session for a member of the owning workspace.","security":[{"ReviewTokenHeader":[]}],"parameters":[{"name":"postIntentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Active review data or a minimal inactive state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewIntentResponse"}}}},"401":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}},"/v1/post-intents/{postIntentId}/confirm":{"post":{"operationId":"publish_tiktok_post","tags":["Publishing"],"summary":"Confirm and consume a prepared TikTok post intent exactly once","description":"For confirmationChannel=agent, authenticate with ApiKeyAuth and confirm only after a new affirmative creator response following display of the complete prepare response. Agent confirmation is disabled by the launch configuration unless the advertised capability is enabled. For browser review with confirmationChannel=browser, the same request must include both ClerkSessionBearer and ReviewTokenHeader, and the Clerk user must belong to the intent's workspace. An exact confirmation replay returns its stored job without a second TikTok publish initialization or usage reservation and remains recoverable after entitlement ends. A racing retry may repeat a safe creator-info metadata read before it observes the winning D1 attempt. Changed confirmation input under the claimed key is rejected.","security":[{"ApiKeyAuth":[]},{"ClerkSessionBearer":[],"ReviewTokenHeader":[]}],"parameters":[{"name":"postIntentId","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntentConfirmation"}}}},"responses":{"200":{"description":"Newly TikTok-accepted Direct Post initialization or the exact stored job recovered by an idempotent replay. Inspect status and publishId before claiming acceptance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishAccepted"}}}},"400":{"$ref":"#/components/responses/ApiError"},"401":{"$ref":"#/components/responses/ApiError"},"402":{"$ref":"#/components/responses/ApiError"},"403":{"description":"Agent-native confirmation is not approved; use the browser review URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"$ref":"#/components/responses/ApiError"},"409":{"description":"The intent or confirmation key is already claimed by a different request, or the intent is not confirmable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"410":{"$ref":"#/components/responses/ApiError"},"413":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"},"502":{"description":"TikTok rejected initialization or its outcome is ambiguous; inspect this intent/job before retrying","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}},"/v1/posts/{jobId}":{"get":{"operationId":"get_tiktok_post_status","tags":["Status"],"summary":"Read the last stored state of an existing TikTok publish job","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}},{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Stored job status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishJobEnvelope"}}}},"400":{"$ref":"#/components/responses/ApiError"},"401":{"$ref":"#/components/responses/ApiError"},"403":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}},"/v1/posts/{jobId}/refresh":{"post":{"operationId":"refresh_tiktok_post_status","tags":["Status"],"summary":"Refresh an existing TikTok publish job from the provider","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}},{"name":"workspaceId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Status refreshed from TikTok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishJobEnvelope"}}}},"400":{"$ref":"#/components/responses/ApiError"},"401":{"$ref":"#/components/responses/ApiError"},"403":{"$ref":"#/components/responses/ApiError"},"404":{"$ref":"#/components/responses/ApiError"},"409":{"$ref":"#/components/responses/ApiError"},"429":{"$ref":"#/components/responses/ApiError"},"502":{"$ref":"#/components/responses/ApiError"},"503":{"$ref":"#/components/responses/ApiError"},"default":{"$ref":"#/components/responses/ApiError"}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"},"ClerkSessionBearer":{"type":"http","scheme":"bearer","bearerFormat":"Clerk session JWT","description":"A current Clerk session token. Browser confirmation also requires ReviewTokenHeader in the same request."},"ReviewTokenHeader":{"type":"apiKey","in":"header","name":"x-review-token","description":"Opaque intent-scoped review capability in agp_review_<64 lowercase hexadecimal characters> form. Legacy bare digest tokens are invalid.","x-token-schema":{"type":"string","minLength":75,"maxLength":75,"pattern":"^agp_review_[a-f0-9]{64}$"}}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"description":"A unique value for this logical operation. Reuse it only to retry the identical request.","schema":{"type":"string","minLength":1,"maxLength":200,"pattern":"\\S"}}},"responses":{"ApiError":{"description":"Actionable API error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"schemas":{"Capabilities":{"type":"object","required":["service","version","network","plan","operations","media","docs","skill","openapi"],"properties":{"service":{"const":"agentic-posting"},"version":{"const":"2026-08-09"},"network":{"const":"tiktok"},"plan":{"type":"object","required":["priceMonthlyUsd","acceptedPublishingRequestsPerBillingPeriod","connectedTikTokAccounts"],"properties":{"priceMonthlyUsd":{"const":8},"acceptedPublishingRequestsPerBillingPeriod":{"const":300},"connectedTikTokAccounts":{"const":1}}},"operations":{"type":"object","required":["upload_tiktok_draft","prepare_tiktok_post","publish_tiktok_post"],"properties":{"upload_tiktok_draft":{"type":"object","required":["available","confirmation"],"properties":{"available":{"const":true},"confirmation":{"const":"finish_in_tiktok"}},"additionalProperties":false},"prepare_tiktok_post":{"type":"object","required":["available","confirmation","expiresInSeconds"],"properties":{"available":{"const":true},"confirmation":{"const":"browser_review"},"expiresInSeconds":{"const":600}},"additionalProperties":false},"publish_tiktok_post":{"type":"object","required":["available","confirmation","fallback"],"properties":{"available":{"type":"boolean","description":"False in the launch configuration; use browser review."},"confirmation":{"const":"separate_expiring_user_response"},"fallback":{"const":"browser_review"}},"additionalProperties":false}},"additionalProperties":false},"media":{"type":"object","required":["retentionHours","workspaceActiveCapacity","video","photo"],"properties":{"retentionHours":{"const":24},"workspaceActiveCapacity":{"type":"object","required":["maxAssets","maxBytes"],"properties":{"maxAssets":{"const":70},"maxBytes":{"const":1000000000}},"additionalProperties":false},"video":{"type":"object","required":["contentTypes","maxBytes","maxAssets"],"properties":{"contentTypes":{"const":["video/mp4"]},"maxBytes":{"const":50000000},"maxAssets":{"const":1}},"additionalProperties":false},"photo":{"type":"object","required":["contentTypes","maxBytesPerAsset","maxAssets"],"properties":{"contentTypes":{"const":["image/jpeg","image/webp"]},"maxBytesPerAsset":{"const":20000000},"maxAssets":{"const":35}},"additionalProperties":false}},"additionalProperties":false},"docs":{"type":"string","format":"uri"},"skill":{"type":"string","format":"uri"},"openapi":{"type":"string","format":"uri"}},"additionalProperties":false},"AgentContext":{"type":"object","required":["workspace","subscription","usage","tiktokAccounts","nextAction"],"properties":{"workspace":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"subscription":{"type":"object","required":["status","planId","publishAccess"],"description":"Webhook-derived Polar entitlement. Only the configured Creator 300 product grants access. An unsupported/missing-product event for the exact stored Polar subscription fails closed to inactive/no-plan; unrelated identities are audit-only. A scheduled cancellation remains publishable only through its future paid period end and never after endedAt. Ended, revoked, past-due, and unscheduled canceled states do not grant publishing access.","properties":{"status":{"type":"string"},"planId":{"enum":["creator","none"]},"publishAccess":{"type":"boolean"}}},"usage":{"oneOf":[{"$ref":"#/components/schemas/Usage"},{"type":"null"}]},"tiktokAccounts":{"type":"array","maxItems":1,"items":{"type":"object","required":["id","username","nickname","isDefault","scopes"],"properties":{"id":{"type":"string"},"username":{"type":["string","null"]},"nickname":{"type":["string","null"]},"isDefault":{"type":"boolean"},"scopes":{"type":"array","items":{"type":"string"},"description":"Draft requires video.upload; Direct Post requires video.publish."}}}},"nextAction":{"type":"object","required":["type"],"properties":{"type":{"enum":["connect_tiktok","manage_billing","ready"]},"url":{"type":"string","format":"uri"}}}}},"UploadReservationRequest":{"type":"object","required":["workspaceId","files"],"properties":{"workspaceId":{"type":"string"},"files":{"description":"One reservation cannot mix media roles: send exactly one video or between 1 and 35 photos.","oneOf":[{"type":"array","minItems":1,"maxItems":1,"items":{"$ref":"#/components/schemas/VideoUploadFile"}},{"type":"array","minItems":1,"maxItems":35,"items":{"$ref":"#/components/schemas/PhotoUploadFile"}}]}}},"VideoUploadFile":{"type":"object","required":["fileName","contentType","sizeBytes","mediaRole","sha256"],"properties":{"fileName":{"type":"string","minLength":1,"maxLength":180},"contentType":{"const":"video/mp4"},"sizeBytes":{"type":"integer","minimum":1,"maximum":50000000},"mediaRole":{"const":"video"},"sha256":{"$ref":"#/components/schemas/LowercaseSha256"}}},"PhotoUploadFile":{"type":"object","required":["fileName","contentType","sizeBytes","mediaRole","sha256"],"properties":{"fileName":{"type":"string","minLength":1,"maxLength":180},"contentType":{"enum":["image/jpeg","image/webp"]},"sizeBytes":{"type":"integer","minimum":1,"maximum":20000000},"mediaRole":{"const":"photo"},"sha256":{"$ref":"#/components/schemas/LowercaseSha256"}}},"LowercaseSha256":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"Required lowercase SHA-256 digest. R2 verifies this while streaming the one-shot upload."},"UploadReservationResponse":{"type":"object","required":["assets"],"properties":{"assets":{"type":"array","minItems":1,"maxItems":35,"items":{"type":"object","required":["assetId","uploadUrl","contentType","expiresAt"],"properties":{"assetId":{"type":"string"},"uploadUrl":{"type":"string","format":"uri"},"contentType":{"enum":["video/mp4","image/jpeg","image/webp"]},"expiresAt":{"type":"integer","description":"Unix timestamp in seconds."}}}}}},"UploadComplete":{"type":"object","required":["ok","assetId","sha256"],"properties":{"ok":{"const":true},"assetId":{"type":"string"},"sha256":{"$ref":"#/components/schemas/LowercaseSha256"}}},"DraftRequest":{"type":"object","required":["workspaceId","accountId","mode","mediaType","assetIds"],"properties":{"workspaceId":{"type":"string"},"accountId":{"type":"string"},"mode":{"const":"draft"},"mediaType":{"enum":["video","photo"]},"assetIds":{"type":"array","minItems":1,"maxItems":35,"uniqueItems":true,"description":"Exactly one asset when mediaType is video; 1-35 ordered assets when mediaType is photo.","items":{"type":"string"}}},"allOf":[{"if":{"properties":{"mediaType":{"const":"video"}}},"then":{"properties":{"assetIds":{"maxItems":1}}}}]},"PostIntentRequest":{"type":"object","required":["path","accountId","mediaType","assetIds","privacyLevel","allowComment","allowDuet","allowStitch","isAigc"],"properties":{"workspaceId":{"type":"string","description":"Optional; defaults to the API key workspace."},"path":{"enum":["DIRECT_PUBLISH","BROWSER_REVIEW"]},"accountId":{"type":"string"},"mediaType":{"enum":["video","photo"]},"assetIds":{"type":"array","minItems":1,"maxItems":35,"uniqueItems":true,"description":"Exactly one asset when mediaType is video; 1-35 ordered assets when mediaType is photo.","items":{"type":"string"}},"title":{"type":"string","maxLength":2200,"description":"TikTok caption for video. Short title of at most 90 characters for photo."},"description":{"type":"string","maxLength":4000,"description":"Photo-post description only. Video intents containing description are rejected because TikTok Direct sends title as the video caption and does not send this field."},"privacyLevel":{"enum":["PUBLIC_TO_EVERYONE","MUTUAL_FOLLOW_FRIENDS","FOLLOWER_OF_CREATOR","SELF_ONLY"]},"allowComment":{"type":"boolean","default":false},"allowDuet":{"type":"boolean","default":false,"description":"Video-only interaction choice. Photo intents must set this to false."},"allowStitch":{"type":"boolean","default":false,"description":"Video-only interaction choice. Photo intents must set this to false."},"commercialContentDisclosure":{"type":"boolean","default":false,"description":"Umbrella disclosure. Must equal brandContentToggle OR brandOrganicToggle."},"brandContentToggle":{"type":"boolean","default":false,"description":"Branded content involving a third-party brand."},"brandOrganicToggle":{"type":"boolean","default":false,"description":"Content promoting the creator's own brand."},"isAigc":{"type":"boolean","description":"Required AI-generated-content disclosure choice. Direct photo intents with true are rejected because TikTok's current direct-photo API has no matching is_aigc field; use draft delivery and complete disclosure in TikTok."},"autoAddMusic":{"type":"boolean","default":false,"description":"Photo-only setting. Omit the property for video intents."},"photoCoverIndex":{"type":"integer","minimum":0,"maximum":34,"default":0,"description":"Photo-only zero-based cover index. It must identify one of this request's ordered assetIds. An omitted photo value is normalized to 0 before hashing, storage, review, and submission. Omit the property for video intents."},"videoCoverTimestampMs":{"type":"integer","minimum":0,"description":"Video-only cover timestamp. Omit the property for photo intents."}},"allOf":[{"if":{"properties":{"mediaType":{"const":"video"}}},"then":{"properties":{"assetIds":{"maxItems":1},"description":{"not":{}},"autoAddMusic":{"not":{}},"photoCoverIndex":{"not":{}}}}},{"if":{"properties":{"mediaType":{"const":"photo"}}},"then":{"properties":{"title":{"maxLength":90},"allowDuet":{"const":false},"allowStitch":{"const":false},"videoCoverTimestampMs":{"not":{}}}}}]},"IntentConfirmation":{"type":"object","required":["approved","confirmationPhrase","contentHash","confirmationChannel"],"properties":{"approved":{"const":true},"confirmationPhrase":{"type":"string","minLength":1,"maxLength":32,"example":"PUBLISH 7K9F"},"contentHash":{"type":"string","pattern":"^sha256:[a-f0-9]{64}$"},"confirmationChannel":{"enum":["agent","browser"]}},"additionalProperties":false},"PostIntent":{"type":"object","required":["postIntentId","mediaType","status","confirmationPhrase","expiresAt","reviewUrl","contentHash","summary","media","confirmation","jobId","failureReason"],"properties":{"postIntentId":{"type":"string"},"mediaType":{"enum":["video","photo"]},"status":{"enum":["awaiting_confirmation","submitting","submitted","submission_unknown","expired","failed"]},"confirmationPhrase":{"oneOf":[{"type":"string"},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time"},"reviewUrl":{"oneOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Present only while this intent is actively awaiting confirmation."},"contentHash":{"type":"string","pattern":"^sha256:[a-f0-9]{64}$"},"summary":{"$ref":"#/components/schemas/IntentSummary"},"media":{"type":"array","maxItems":35,"description":"Ordered review media. Active newly prepared intents contain 1-35 items; a later authenticated read can be empty after temporary media retention cleanup.","items":{"$ref":"#/components/schemas/IntentMedia"}},"confirmation":{"oneOf":[{"$ref":"#/components/schemas/IntentConfirmationMetadata"},{"type":"null"}]},"jobId":{"type":["string","null"]},"failureReason":{"type":["string","null"]}}},"IntentMedia":{"type":"object","required":["assetId","contentType","previewUrl"],"properties":{"assetId":{"type":"string"},"contentType":{"enum":["video/mp4","image/jpeg","image/webp"]},"previewUrl":{"type":"string","format":"uri"}},"additionalProperties":false},"IntentConfirmationMetadata":{"type":"object","required":["endpoint","method","requiresSeparateUserResponse","allowedChannels"],"properties":{"endpoint":{"type":"string","pattern":"^/v1/post-intents/[^/]+/confirm$"},"method":{"const":"POST"},"requiresSeparateUserResponse":{"const":true},"allowedChannels":{"type":"array","minItems":1,"maxItems":2,"uniqueItems":true,"items":{"enum":["agent","browser"]}}},"additionalProperties":false},"InactiveReviewIntent":{"type":"object","required":["postIntentId","status","expiresAt"],"properties":{"postIntentId":{"type":"string"},"status":{"enum":["submitting","submitted","submission_unknown","expired","failed"]},"expiresAt":{"type":"string","format":"date-time"}},"additionalProperties":false},"ReviewIntentResponse":{"oneOf":[{"$ref":"#/components/schemas/PostIntent"},{"$ref":"#/components/schemas/InactiveReviewIntent"}]},"IntentSummary":{"type":"object","required":["creator","title","description","privacy","comments","duet","stitch","aiGenerated","autoAddMusic","photoCoverIndex","videoCoverTimestampMs","commercialContentDisclosure","brandOrganicToggle","brandContentToggle"],"properties":{"creator":{"type":"string","minLength":1,"description":"Nonblank recognizable TikTok username or nickname. Intent preparation fails closed if TikTok supplies neither."},"title":{"type":["string","null"],"description":"Video caption or photo short title."},"description":{"type":["string","null"],"description":"Photo description. Video intents reject this field."},"caption":{"type":"string","deprecated":true,"description":"Compatibility alias. New clients must review title and description independently."},"privacy":{"type":"string"},"comments":{"enum":["On","Off"]},"duet":{"enum":["On","Off"]},"stitch":{"enum":["On","Off"]},"aiGenerated":{"enum":["Yes","No"]},"autoAddMusic":{"type":"boolean","description":"Whether TikTok should automatically add recommended music for a photo post."},"photoCoverIndex":{"type":["integer","null"],"minimum":0,"maximum":34,"description":"Effective zero-based cover-photo index. Photo intents always expose an integer and default omitted input to 0; video intents expose null."},"videoCoverTimestampMs":{"type":["integer","null"],"minimum":0,"description":"Video cover timestamp in milliseconds; null when not selected or not applicable."},"commercialContentDisclosure":{"type":"boolean"},"brandOrganicToggle":{"type":"boolean","description":"Your brand."},"brandContentToggle":{"type":"boolean","description":"Branded content."},"commercialDisclosure":{"type":"string","deprecated":true,"description":"Compatibility label. New clients must review the three boolean disclosure fields independently."}}},"Usage":{"type":"object","required":["used","reserved","limit","remaining","periodStart","periodEnd"],"properties":{"used":{"type":"integer","description":"TikTok-accepted initialization units whose accepted_at timestamp falls within this Polar billing period."},"reserved":{"type":"integer","description":"Unresolved provider-attempt capacity holds. These are not accepted usage, but remain reserved across billing-period boundaries until internal provider/operator evidence reconciles them. A missing-publish-id hold has no public reconciliation or release endpoint and no automatic expiry."},"limit":{"type":"integer","const":300},"remaining":{"type":"integer","description":"max(limit - used - reserved, 0)."},"periodStart":{"type":"integer"},"periodEnd":{"type":"integer"}}},"PublishAccepted":{"type":"object","required":["jobId","publishId","status","usage"],"properties":{"jobId":{"type":"string"},"publishId":{"type":["string","null"]},"status":{"type":"string","description":"Initialization/job state. TikTok acceptance is not proof that publication is complete."},"usage":{"oneOf":[{"$ref":"#/components/schemas/Usage"},{"type":"null"}],"description":"Current read-only usage snapshot when available. Idempotent recovery remains valid if entitlement ended or this optional snapshot could not be read."}}},"PublishJobResult":{"type":"object","required":["jobId","publishId","status","usage"],"properties":{"jobId":{"type":"string"},"publishId":{"type":["string","null"]},"status":{"type":"string","description":"The exact stored job state. submission_unknown means TikTok may have received initialization; do not create a replacement."},"nextAction":{"type":"string"},"usage":{"oneOf":[{"$ref":"#/components/schemas/Usage"},{"type":"null"}],"description":"Current read-only usage snapshot when available. Idempotent recovery remains valid if entitlement ended or this optional snapshot could not be read."}}},"PublishJobEnvelope":{"type":"object","additionalProperties":false,"required":["job","metrics"],"properties":{"job":{"type":"object","additionalProperties":false,"required":["id","status","publishId","tiktokPostId","failReason"],"properties":{"id":{"type":"string"},"status":{"type":"string","description":"Stored lowercase job state. Known values include queued, processing, processing_upload, processing_download, send_to_user_inbox, publish_complete, failed, submission_unknown, and no_longer_publicly_available. TikTok may add provider states."},"publishId":{"type":["string","null"]},"tiktokPostId":{"type":["string","null"]},"failReason":{"type":["string","null"]}}},"metrics":{"type":["object","null"]}}},"ErrorEnvelope":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}}}}}}}}