Skip to Content
Combos SDKAPI reference

Combos SDK API reference

SDK 1.1.0 · Checked on 2026-10-13. This is the game-facing JavaScript API exposed as window.combos. It documents all 10 global methods and the TikTok client’s 4 methods. Find a method below for its exact inputs, result, failure behavior, and example. For a complete game, follow the TikTok tutorial; for UI wiring, see accounts and localization.

Calls go through the Combos host. These are JavaScript methods, not REST endpoints: there is no API base URL, API key, HTTP status envelope, or manual postMessage to construct in your game. A resolved value is the result itself, without a data wrapper.

Runtime and TypeScript setup

The supported Combos player injects the SDK. Do not install a second runtime script or overwrite window.combos. A standalone website or local preview may not have the global; check it in browser code and keep the basic game available. Do not access window during server rendering.

For editor completion, save the public declaration  as combos-host-sdk.d.ts beside your game source and include that directory in your TypeScript project. The file supplies types only. The examples that import TTLiveClient use import type, which adds no runtime dependency.

curl --fail --location https://combos.converge.ai/host-sdk.d.ts --output ./combos-host-sdk.d.ts
async function readCapabilities() { const sdk = window.combos; if (!sdk) return []; const { methods } = await sdk.init(); return methods; }

Each TypeScript block is an independent helper; invoke it from your own UI and catch rejected promises. Functions ending in AfterClick belong in a player-initiated action. A helper’s null means unavailable or cancelled as shown in its code; this is not an extra SDK return value. JSON blocks illustrate raw request or result shapes, with fictional identities and times. Example UI strings should use your game’s language.

Method index

MethodPurposeHost request timeout
init()Discover capabilities3 seconds, then compatibility fallback
checkSession()Read current login state10 seconds
login()Open host login5 minutes
getUserInfo()Read game-scoped player identity10 seconds
requestI18n(params)Translate visible source text30 seconds
getSetting()Read Cloud Ability decisions10 seconds
authorize(params)Ask for one permission5 minutes
openSetting()Open host permission settings5 minutes
getCloudAbilitySession()Obtain a short-lived session10 seconds
getTTLiveClient()Get this document’s clientSynchronous; no request
client.connect(options)Start the interaction streamOwn lifecycle; no fixed overall deadline
client.getLiveStatus()Query interaction statusSession request, then up to 5 seconds for HTTP
client.onStatusChange(listener)Subscribe to statusSynchronous
client.disconnect()Stop this clientSynchronous

The first host call can also spend up to 3 seconds discovering capabilities. These are SDK waiting limits, not service-level guarantees. The public methods do not accept timeout, AbortSignal, callback-style success handlers, or extra identity parameters.

Check support before calling

Use init().methods, not just the presence of a function. In the current Web host, checkSession and login are supported; getUserInfo depends on a trusted game context, requestI18n on the Play host’s translation support, and TikTok on its host capability and registered launch context. Older Web and App hosts can differ.

The current Web host does not advertise getSetting, authorize, openSetting, or getCloudAbilitySession. Their contract is documented for hosts that explicitly advertise them. Publishing a game does not enable Cloud Ability or TikTok automatically. A method missing from the capability list rejects with unsupported before that method’s host request is sent.

getTTLiveSession is an internal capability name. Check for it before using getTTLiveClient(); there is no public combos.getTTLiveSession() method. The global API also has no logout, generic request, cloud-save, payment, leaderboard, or gift-registration method.

Initialization and accounts

combos.init()

combos.init(): Promise<ICombosHostInitResult>

Parameters: none. Login required: no. Returns: a promise containing methods, an array of supported capability names. It does not sign the player in, open UI, or start a TikTok connection.

Concurrent calls share discovery; the result is cached for the current game document. Other host methods call discovery automatically. Unknown names and duplicates in a valid list are filtered out. If discovery fails, the payload is invalid, or the host is silent for 3 seconds, it resolves with ['checkSession', 'login']. A valid empty list remains empty. The fallback is compatibility behavior, not proof that a standalone page has a working host. Later calls can still time out. There is no public force-refresh option.

The following response is illustrative; do not hard-code its methods as universally available.

interface ICombosHostInitResult { methods: Array< | 'checkSession' | 'login' | 'getUserInfo' | 'requestI18n' | 'getSetting' | 'authorize' | 'openSetting' | 'getCloudAbilitySession' | 'getTTLiveSession' >; }
{ "methods": ["checkSession", "login", "getUserInfo", "requestI18n", "getTTLiveSession"] }

combos.checkSession()

combos.checkSession(): Promise<boolean>

Parameters: none. Login required: no. Returns: true when the host reports a signed-in session, otherwise false. It reads state without opening the login UI. The SDK only treats the exact boolean true as signed in; truthy strings or objects are not accepted.

Read it immediately before each independent account action. Do not cache the result as a permanent login guarantee: the session can change after the check. A transport error or timeout rejects; it must not be treated as a normal false or proof of logout. If it returns false, let the player choose login. After a successful login() for the same action, continue directly without another check.

async function readSession() { const sdk = window.combos; if (!sdk) return null; const { methods } = await sdk.init(); if (!methods.includes('checkSession')) return null; return sdk.checkSession(); }

combos.login()

combos.login(): Promise<ICombosHostLoginResult>

Parameters: none; never send an account ID, password, or token. Login required: no. Side effect: opens the host’s login flow when needed. Call from a player action and disable the initiating control while pending.

statusMeaning and next step
successThe current action can continue; no reload, polling, or second session check is required
cancelledThe player cancelled; return to the game without an error loop or automatic prompt

Cancellation resolves normally. A blocked popup, transport failure, login synchronization failure, or timeout rejects. A malformed result or unknown status becomes request_failed. On the current Web host, an already signed-in player gets success without a new login. The result contains no credentials or player profile; request the latter separately.

interface ICombosHostLoginResult { status: 'success' | 'cancelled'; }
async function loginAfterClick() { const sdk = window.combos; if (!sdk) return null; const { methods } = await sdk.init(); if (!methods.includes('checkSession') || !methods.includes('login')) return null; if (await sdk.checkSession()) return { status: 'success' as const }; return sdk.login(); }
{ "status": "success" }

combos.getUserInfo()

combos.getUserInfo(): Promise<ICombosHostUserInfo>

Parameters: none. Preconditions: getUserInfo is advertised, the host has a trusted game context, and a session exists. A logged-out call rejects with session_required. A preceding successful session check does not eliminate the need to catch a later expiry.

FieldType / presenceMeaning
appIdRequired, non-empty stringCurrent game’s app identity; not a Post URL or a game-supplied project ID
openIdRequired, non-empty stringPlayer identity within this app; use together with appId
nickNameRequired string, may be emptyDisplay name; provide a fallback
avatarUrlRequired string, may be emptyDisplay avatar; use your fallback when missing or loading fails
localeRequired, non-empty stringPlayer’s saved public language, such as en or zh-CN; the current product language when none is saved

The response has no email, phone number, platform user ID, login token, or Cloud Ability session. Do not infer identity across different apps from openId, or use this browser response as authentication proof for your server. Treat display strings as text, not HTML. Missing identities, non-string display fields, or another invalid result cause request_failed; host/backend errors can carry additional codes.

interface ICombosHostUserInfo { appId: string; openId: string; nickName: string; avatarUrl: string; locale: string; }
async function readPlayerAfterClick() { const sdk = window.combos; if (!sdk) return null; const { methods } = await sdk.init(); if (!methods.includes('checkSession') || !methods.includes('login') || !methods.includes('getUserInfo')) return null; if (!(await sdk.checkSession())) { const login = await sdk.login(); if (login.status === 'cancelled') return null; } return sdk.getUserInfo(); }
{ "appId": "app_example", "openId": "player_example", "nickName": "Alex", "avatarUrl": "", "locale": "en" }

Game localization

combos.requestI18n(params)

combos.requestI18n(params: ICombosHostRequestI18nParams): Promise<ICombosHostI18nResult>

Login required: no login prerequisite in the current Web translation bridge. The host must advertise requestI18n. Render source text first; translation is an optional asynchronous enhancement, not a loading gate.

ParameterTypeRequiredMeaning
sourceLocalestringYesLanguage of the supplied source text, such as en or zh-CN; not the target language
sourceTextsstring[]YesExact source strings or stable templates already shown by the game

There is no targetLocale parameter. The host selects its current product language. Current Web handling trims the locale, skips empty/non-string text entries, deduplicates equal source strings, and sends translation requests in batches of 50. That batch size is not a public SDK input limit. Prefer small groups of stable UI text so they can finish within the 30-second request window; do not translate every animation frame.

interface ICombosHostRequestI18nParams { sourceLocale: string; sourceTexts: string[]; } type ICombosHostI18nResult = | { needed: false } | { needed: true; locale: string; translations: Record<string, string> };
{ "sourceLocale": "en", "sourceTexts": ["Play", "Score: {score}"] }
{ "needed": true, "locale": "zh-CN", "translations": { "Play": "开始", "Score: {score}": "得分:{score}" } }
Return fieldMeaning
needed: falseKeep all source text. locale and translations are absent in this branch
needed: trueTranslation results are available; the mapping can still be partial
localeTarget locale selected by the host; present only when needed is true
translationsSource string → translated string; keys are exact source text, not your application IDs

Equivalent source/host languages, no usable text, unavailable translation, and current Web backend translation failures can all resolve to { needed: false }. The SDK also turns malformed translation results into that branch. Unsupported methods and transport timeouts can still reject. For each missing or empty translation, keep that original string. Apply with textContent, never innerHTML.

Translate templates such as Score: {score} before inserting values; the SDK does not interpolate placeholders. Check that required placeholders remain before applying a translated template. Preserve the original source strings between calls instead of retranslating already translated text with an outdated sourceLocale.

async function translateVisibleLabels(nodes: HTMLElement[]) { const sourceTexts = nodes.map(node => node.textContent ?? ''); const sdk = window.combos; if (!sdk) return; try { const { methods } = await sdk.init(); if (!methods.includes('requestI18n')) return; const result = await sdk.requestI18n({ sourceLocale: 'en', sourceTexts }); if (!result.needed) return; nodes.forEach((node, index) => { node.textContent = result.translations[sourceTexts[index]] || sourceTexts[index]; }); } catch { // Source text stays visible. } }

Optional Cloud Ability APIs

These four methods are not advertised by the current Web host. Detect each method individually. The examples are conditional integration code for a supporting host, not a way to enable the feature. A successful authorization record also does not prove that the game owner has enabled the underlying ability.

type CombosHostPermissionScope = 'ai_model'; type CombosHostAuthorizationDecision = | 'AUTHORIZATION_DECISION_UNSPECIFIED' | 'AUTHORIZATION_DECISION_GRANTED' | 'AUTHORIZATION_DECISION_DENIED'; interface ICombosHostPlayableAuthorization { decision: CombosHostAuthorizationDecision; decidedAtMs: number; } type ICombosHostAuthSetting = Readonly< Partial<Record<CombosHostPermissionScope, ICombosHostPlayableAuthorization>> >; interface ICombosHostAuthorizeParams { scope: CombosHostPermissionScope } interface ICombosHostCloudAbilitySession { session: string; expiresAtMs: number }
Field / valueContract
scopeOnly 'ai_model' is currently defined; required by authorize
decisionRuntime accepts AUTHORIZATION_DECISION_GRANTED or AUTHORIZATION_DECISION_DENIED
AUTHORIZATION_DECISION_UNSPECIFIEDAppears in the exported union as a zero value; it is not a valid returned decision accepted by this SDK
decidedAtMsRequired finite number, Unix time in milliseconds; not seconds or an expiry time
Missing ai_model keyThe player has never been asked for this game’s scope; distinct from denial
sessionRequired non-empty credential string; sensitive, short-lived, memory only
expiresAtMsRequired finite number, Unix expiry time in milliseconds; no fixed TTL is promised

These APIs take no user, device, project, Post, or play-instance IDs. The host supplies the trusted context and owns login/permission UI. Meet that host’s session requirements before protected actions. Do not loop permission prompts when permission is denied.

combos.getSetting()

combos.getSetting(): Promise<ICombosHostAuthSetting>

Parameters: none. Timeout: 10 seconds. Reads the current player’s decisions for the current game without opening permission settings. Resolves to ICombosHostAuthSetting; {} is a valid result when the ai_model decision is absent.

The SDK projects only the known ai_model scope. If that scope exists, both a granted/denied decision and finite decidedAtMs are required; an invalid record rejects with request_failed. Do not reinterpret an absent scope as denial, or keep a stale decision after the player changes settings.

{ "ai_model": { "decision": "AUTHORIZATION_DECISION_GRANTED", "decidedAtMs": 1791800000000 } }
async function readPermissionSettings() { const sdk = window.combos; if (!sdk) return null; const { methods } = await sdk.init(); if (!methods.includes('getSetting')) return null; return sdk.getSetting(); }

combos.authorize(params)

combos.authorize(params: ICombosHostAuthorizeParams): Promise<ICombosHostPlayableAuthorization>

Parameters: one required object with scope: 'ai_model'; no default, wildcard, scope array, or caller-supplied decision. Timeout: 5 minutes. This is an interactive host-owned permission request; start it from a player action.

Returns one authorization record, not the complete settings object. AUTHORIZATION_DECISION_DENIED is a normal resolved result. Only proceed with an authorized action after GRANTED; denial is not a reason to reprompt automatically. There is no cancelled result in this method’s contract. A host UI dismissal must be interpreted through the actual returned record or rejection, not through the login API’s statuses. Unsupported hosts, invalid returned records, transport errors, and timeouts reject.

async function requestAiPermissionAfterClick() { const sdk = window.combos; if (!sdk) return null; const { methods } = await sdk.init(); if (!methods.includes('authorize')) return null; return sdk.authorize({ scope: 'ai_model' }); }
{ "decision": "AUTHORIZATION_DECISION_DENIED", "decidedAtMs": 1791800000000 }

combos.openSetting()

combos.openSetting(): Promise<ICombosHostAuthSetting>

Parameters: none. Timeout: 5 minutes. Opens the host’s permission settings from a player action and resolves with the resulting ICombosHostAuthSetting. It does not accept an object to grant permissions silently.

Use the returned settings to refresh your UI, including the possibility of a missing or denied scope. The return value is not a boolean, a single authorization record, or a login status. The same record validation as getSetting() applies. Unsupported methods, invalid results, and host/transport failures reject. The SDK does not specify a separate cancellation status.

async function openPermissionsAfterClick() { const sdk = window.combos; if (!sdk) return null; const { methods } = await sdk.init(); if (!methods.includes('openSetting')) return null; return sdk.openSetting(); }

combos.getCloudAbilitySession()

combos.getCloudAbilitySession(): Promise<ICombosHostCloudAbilitySession>

Parameters: none. Timeout: 10 seconds. Resolves with { session, expiresAtMs } for the current play in a supporting host. The call itself does not display an authorization prompt or prove access to every AI model. Handle the host’s session, permission, and ability-availability errors.

Keep the credential in memory and use it only with the supported Cloud Ability integration documented by that host. Never place it in logs, screenshots, URLs, local storage, or source code. Check expiry before use, obtain a fresh session when needed, and discard the old value when the player/play changes. This public API has no refreshToken, TTL parameter, or general-purpose backend authentication guarantee. A malformed result rejects with request_failed.

async function obtainCloudSession() { const sdk = window.combos; if (!sdk) return null; const { methods } = await sdk.init(); if (!methods.includes('getCloudAbilitySession')) return null; const value = await sdk.getCloudAbilitySession(); if (value.expiresAtMs <= Date.now()) throw new Error('Session already expired'); return value; // Keep in memory only; never log or persist this value. }

TikTok client reference

Real TikTok integration currently has no available activation path. The API contract below does not mean that a newly published game can receive real gifts. You can build the game, run the simulator, and publish it to Combos; real integration must wait for the platform to provide an activation process.

The client manages this game’s TikTok interaction session, not the broadcaster’s overall LIVE status. It owns transport, heartbeats, session renewal, and reconnects. The game owns supported instructions, effect execution, durable deduplication, and truthful results. Gift mapping concepts, publication, preparation materials, and the runnable project are in the complete tutorial.

combos.getTTLiveClient()

combos.getTTLiveClient(): TTLiveClient

Parameters: none. Returns: a TTLiveClient synchronously, with no network request at getter time. Repeated calls return the same instance for this SDK/game document; do not create competing controllers for different components.

Check getTTLiveSession in the capability list as shown below. A client object alone proves neither host support, login, a registered launch, nor successful connection. Perform the account flow before starting a real connection. Provider keys, CAS credentials, launchData, and raw WebSocket URLs are handled internally; there are no parameters for supplying them here.

async function getTikTokClient() { const sdk = window.combos; if (!sdk || typeof sdk.getTTLiveClient !== 'function') return null; const { methods } = await sdk.init(); if (!methods.includes('getTTLiveSession')) return null; return sdk.getTTLiveClient(); }

client.connect(options)

client.connect(options: TTLiveConnectOptions): Promise<void>

Parameters: one required options object. Its required onCommand must be a function returning boolean or Promise<boolean>. There are no room ID, streamer ID, token, reconnect, or timeout options in this public signature.

Returns Promise<void> after the stream’s ready frame. This is not proof of a gift effect or permanent connectivity; observe status separately. Recovery can leave the promise pending indefinitely. Expose a stop action before awaiting it. Calling connect again while already desired reuses the pending connection or resolves immediately; it does not replace the original handler. Disconnect before changing handlers.

Missing onCommand rejects with a plain Error. Explicit disconnection or a terminal state before readiness also rejects the pending promise. Transient transport/session failures generally enter recovery instead of immediately rejecting. Distinct command IDs can invoke asynchronous handlers concurrently; serialize shared state changes or use transactions in your game.

interface TTLiveConnectOptions { onCommand: (command: TTLiveCommand) => boolean | Promise<boolean>; } interface TTLiveCommand { messageId: string; instruction: string; count: string; timestamp: string; }
Callback fieldType / validationGame responsibility
messageIdNon-empty string, at most 256 characters in SDK 1.1.0Opaque idempotency key; persist execution outcome with the effect
instructionstringMatch your declared instructions; the SDK does not validate your gift catalog
countDecimal digit string, retaining large integer precisionValidate business limits before conversion; do not use Number blindly. SDK parsing alone does not reject zero or leading zeros
timestampstringSource time representation; the public type does not promise a unit or format. Do not use as identity or ordering proof

The example below is an illustrative command, not a gift-registration API. There are no viewer IDs, display names, gift prices, or real gift IDs in this callback. count is the mapped instruction quantity, not necessarily the number of gifts or their coin value.

{ "messageId": "example-command-001", "instruction": "gift_flash", "count": "3", "timestamp": "1791800000" }
Handler outcomeSDK behavior
true / promise resolving trueReport successful execution; return only after effect and receipt are committed
false / promise resolving falseReport a definite rejection/failure, such as an unsupported instruction with no effect
Throw / rejected promise / non-boolean resultOutcome stays unknown and unacknowledged; the SDK reconnects and the command may return

SDK memory deduplication is limited and is cleared by explicit disconnect or document reload. It is not durable exactly-once execution. Store messageId, the effect, and its result atomically; replay a saved result for duplicates. Do not return false after a partial side effect whose outcome is uncertain. The Gift Arena example implements this with a transaction.

This helper makes cancellation available immediately and registers rejection handling. Supply your real command handler and non-throwing UI callbacks; connected can still be awaited. Keep the returned stop function for both pending and established connections.

import type { TTLiveClient, TTLiveConnectOptions, TTLiveStatus } from './combos-host-sdk'; function attachTikTok( client: TTLiveClient, onCommand: TTLiveConnectOptions['onCommand'], onStatus: (status: TTLiveStatus) => void, onConnectionError: (error: unknown) => void, ) { const unsubscribe = client.onStatusChange(onStatus); const connected = client.connect({ onCommand }); void connected.catch(onConnectionError); return { connected, stop() { unsubscribe(); client.disconnect(); }, }; }

client.getLiveStatus()

client.getLiveStatus(): Promise<TTLiveStatus>

Parameters: none. Performs a current status check, publishes the result to status listeners, and resolves to TTLiveStatus. It does not start the command stream. Internally it obtains the host session (10-second host request, plus initial discovery if needed), then applies a 5-second limit to the status HTTP request.

Network, HTTP, session parsing, and invalid status payload failures are represented as status results, usually unknown, rather than proof of ended. A host tt_not_launched result becomes ended with relaunch_game. A returned terminal state also stops an active client. Prefer subscriptions during play instead of repeatedly polling this method.

interface TTLiveStatus { state: 'connecting' | 'connected' | 'recovering' | 'ended' | 'unknown'; reason: string; action: 'none' | 'wait' | 'relaunch_game'; confirmedAtMs: number; }
Field / valueMeaning / action
state: connectingInitial connection is being established
state: connectedThis game’s interaction session was confirmed
state: recoveringThe SDK is recovering transport; allow its retry lifecycle
state: unknownConfirmation is unavailable; do not declare the broadcast ended
state: endedThis interaction session ended; inspect action
reasonDiagnostic string, may be empty or gain new values; not a closed enum
action: noneNo recovery action requested
action: waitWait for status recovery; keep a cancel control
action: relaunch_gameAsk the streamer to reopen this game from LIVE Studio, not to restart the broadcast
confirmedAtMsUnix milliseconds of the latest confirmed TikTok start/heartbeat; 0 means unknown, not an expiry timestamp

Known reason strings include platform_unconfirmed, transport_unavailable, client_disconnected, tt_not_launched, and session_required. Drive recovery from state and action; do not assume this list is exhaustive or display raw reasons as finished player copy.

import type { TTLiveClient } from './combos-host-sdk'; async function checkTikTokStatus(client: TTLiveClient) { const status = await client.getLiveStatus(); return status; }
{ "state": "unknown", "reason": "transport_unavailable", "action": "wait", "confirmedAtMs": 0 }

client.onStatusChange(listener)

client.onStatusChange(listener: (status: TTLiveStatus) => void): () => void

Parameters: a required synchronous listener receiving TTLiveStatus. Returns: an unsubscribe function. The listener runs immediately with the current status, then when status fields change; heartbeat confirmation times can cause updates even if state stays the same.

Unsubscribe when the owning UI is removed. Removing a listener does not disconnect the client; disconnecting does not remove your listeners. Do not throw inside the listener: the immediate invocation can propagate a consumer error. The example prints protocol values for debugging; localize production status messages.

import type { TTLiveClient } from './combos-host-sdk'; function showTikTokStatus(client: TTLiveClient, output: HTMLElement) { const unsubscribe = client.onStatusChange(status => { output.textContent = `${status.state} · ${status.action}`; }); return unsubscribe; // Call when the UI is removed. }

client.disconnect()

client.disconnect(): void

Parameters: none. Returns: undefined (void). Stops timers, pending retries, and the socket; clears the client’s in-memory execution/results cache; rejects a still-pending connect promise. It publishes unknown / client_disconnected / wait with confirmedAtMs: 0.

This is not a synchronous TikTok end-broadcast API or proof of a server-side end ACK. It does not delete your saved receipts and cannot roll back a handler already executing. Unsubscribe your UI separately, guard late game work, and retain durable receipts. The same client can connect again afterward; repeating disconnection is safe for cleanup.

import type { TTLiveClient } from './combos-host-sdk'; function stopTikTok(client: TTLiveClient, unsubscribe: () => void) { unsubscribe(); client.disconnect(); }

Errors and recovery

Host-method failures reject with an Error carrying string code and message. Match code, not the human-readable message. The list below is not exhaustive: host/backend codes can pass through. TikTok lifecycle failures can be plain Error objects without code; getLiveStatus intentionally represents many failures as status values instead.

Keep normal decisions distinct from failures: checkSession() === false, login cancelled, authorization DENIED, and translation needed: false are resolved results. The following helper preserves that distinction and handles errors without assuming a particular class or logging credentials.

function readErrorCode(error: unknown): string | null { if (error && typeof error === 'object' && 'code' in error && typeof error.code === 'string') { return error.code; } return null; } async function checkAccountSafely() { const sdk = window.combos; if (!sdk) return { kind: 'unavailable' as const }; try { return { kind: 'success' as const, signedIn: await sdk.checkSession() }; } catch (error) { return { kind: 'error' as const, code: readErrorCode(error) }; } }
CodeMeaningRecovery
unsupportedThe host did not advertise this methodHide/disable the optional capability; keep base gameplay
timeoutSDK waiting window expiredEnd the loading state and offer a player-initiated retry; do not assume the host cancelled the operation
transport_failedSending the host request failedCheck the supported player environment; retain fallback UI
request_failedHost failure or malformed resultCatch the error, inspect the affected action, and retry only when safe
disposedThis SDK document/client was torn downStop callbacks/work for that document; do not retry it in a loop
session_requiredThe account session is unavailableOffer login, then retry the intended action after success
model_not_supportedHost/backend rejected the requested modelUse a model supported by the relevant Cloud Ability integration
100250001Permission request validation failedCheck the supported scope and host’s trusted game context
100260001 / 100260002Session creation/context invalid or session invalidRe-establish the authorized play/session; do not fabricate IDs or credentials
100260004AI-model authorization is missingRespect the permission decision and use host authorization when supported
100260005The game capability is closedHave the game owner verify capability availability; repeated login will not enable it

Numeric codes above are known host/backend codes, not guarantees that the current Web host exposes Cloud Ability. Use the method-level availability rules first. For unknown codes, show a recoverable error and record only non-sensitive diagnostics.

TikTok reason and action are status fields, not host error codes. A rejected command handler does not produce a failed ACK automatically. Do not implement catch(() => false) around effects that may already have occurred. Similarly, a host timeout only stops SDK waiting; there is no public cancellation method for login, authorization, or translation. Avoid automatic retries that reopen UI or repeat an uncertain action.

Lifecycle and integration boundaries

  1. Read capabilities once for the document; check the current account immediately before each new account action.
  2. Bind login and permission requests to a player action. Handle cancellation/denial without reopening the same prompt.
  3. Keep translation optional and source text visible. Discard stale asynchronous UI results when a scene has been removed.
  4. Give one owner responsibility for the document’s TikTok client. Register status, connect with a durable handler, and allow cancellation while pending.
  5. Unsubscribe and disconnect when leaving the interaction. Preserve execution receipts, and discard sensitive sessions when their play/account ends.

There is no public SDK-wide dispose(), account-change event, login cancellation handle, or global request-timeout setting on window.combos. Do not call internal classes or undocumented host HTTP routes to fill these gaps. Downloadable demo code and its sample storage limits are game choices, not additional SDK APIs.

Version, types, and complete examples

The public TypeScript declaration  is the authoritative editor-facing shape. This reference also checks SDK 1.1.0 runtime validation, timeouts, Web-host capability selection, translation handling, and TikTok lifecycle behavior. Type presence alone does not establish runtime availability, and future SDK/host versions can change behavior.

Documentation examples are checked against the public types. That check and the local simulator do not establish real-account login, Cloud Ability access, or successful paid-gift delivery; validate those flows in an eligible host with the appropriate account and registered game.

Last updated on