Skip to main content
Authenticate these GraphQL operations with Authorization: Bearer <APOB_API_KEY> as described in authentication. Every selection is checked against the authenticated account and its Chat session.
The Chat capabilities talking_avatar, lip_sync, and generate_audio currently prepare inputs only. Their schema returns preparationOnly: true and submissionSupported: false. Input readiness does not create a task, produce a quote, or charge credits. Existing direct speech and avatar mutations retain their own generation contracts. Local implementation does not establish hosted availability.
You can prepare, edit, and validate these inputs while generation is unavailable. A saved voice selection remains selected during follow-up requests; preparation checks its current availability again. Explicit discussion and settings queries do not validate or submit a draft. Settings replies show the audio input mode and, for voice-script inputs, the selected voice name and original script. Voice names are checked for current access and readiness before display. A settings query does not change the saved inputs or create a quote.

Upload or select audio

Use the existing Chat upload sequence:
  1. Create a session with createChatSession(input: CreateChatSessionInput!) if needed. The input requires a unique clientRequestId; title is optional.
  2. Call initChatUpload(input: InitChatUploadInput!). Supply sessionId, a unique clientRequestId, fileName, mimeType, the file’s hexadecimal SHA-256, and fileSize in bytes. runId is optional before the first message.
  3. Upload the bytes to the returned uploadUrl using HTTP PUT and the returned headers, before expiresAt.
  4. Call completeChatUpload(uploadId: ID!, runId: ID) and read chatUpload(uploadId: ID!).
Supported audio MIME types are audio/mpeg, audio/mp4, audio/wav, audio/x-wav, audio/vnd.wave, audio/ogg, and audio/flac. The existing 200 MiB file-size limit applies. Audio uploads have no duration limit. Completion validates the uploaded object and probes its actual duration. A failed probe leaves the upload unusable; retry completion while the upload is available. Generation-specific duration limits belong to the generation service when that workflow is connected. A ready chatUpload response is a JSON object with fileType: "audio", fileName, durationMs, playbackUrl, and an identity-only asset. Playback URLs expire; read the metadata again to refresh them. Never persist signed URLs as an input identity. chatReferences(sessionId: ID!, references: [ChatAssetReferenceInput!]!) restores authorized attachment metadata, including audio playback and duration. Existing generated audio remains a MEDIA resource. Query chatAssets with fileType: "audio", a session or run, and source: "LIBRARY", "HISTORY", or "COMMUNITY". Select the result explicitly before binding it to a draft.

Select a voice

ChatVoiceModels
The result is a ChatJSON object, so it has no GraphQL selection set. pageNumber * limit must not exceed 1,000. The response includes items, hasMore, pageNumber, limit, and source. Items contain modelId, name, selectable, and unavailableReason; an existing audio preview may also provide playbackUrl. Browsing never generates a preview. Selection readiness is checked again during input preparation, including whether the voice has a usable reference. items contains at most limit voices. Availability filtering can produce a shorter page even when hasMore is true; continue with the next pageNumber using the same limit. The lookahead record used to determine hasMore is not included in the current page.

Save a draft

Use the existing sendChatMessage.input.parameterPatch or answerChatRun.input.parameterPatch and assetBindings. Send the actual speech as voiceScript, preserving its wording. The script must be nonblank and no more than 8,000 characters. A voice model must be selected explicitly.
Voice-script parameter patch
For file input, set audioInputMode: "AUDIO_FILE" and supply this binding:
Audio asset binding
Talking Avatar also requires inputImage; Lip Sync also requires inputVideo. Generate Audio accepts only the voice-script path and requires no visual input. chatWorkflowSchema(sessionId: ID!, workflowId: String!, runId: ID, parameters: ChatJSON, assetBindings: [ChatAssetBindingInput!]) describes the current required fields, slots, and preparation-only status. Partial inputs remain editable. Missing or conflicting inputs return to the input step. An explicit mode switch clears the previous mode’s active inputs; uploaded files and historical attachments are retained. Concurrently supplied conflicting inputs still require correction: validation returns field audioInputMode with reason AUDIO_INPUT_CONFLICT, including when a mode or visual input is missing. Edits and undo retain the draft’s exact script; ordinary image-to-video, text-to-video, and Extend continue using dialogue in their prompt fields.

Create a reusable voice model

The separate create_voice_model Chat workflow creates one independent voice model from one ready audio upload or authorized audio MEDIA. It supports a complete confirmation and creation flow, including an audio preview. This does not change the preparation-only limits of the three workflows described above. Check chatWorkflowSchema on your deployment before offering the action. Bind the sample to inputAudio. Creating a voice does not require an existing voiceModelId, voiceScript, or audioInputMode. Portrait association, multiple samples, custom avatars, tags, and creating a voice from a text-only description are not supported in this Chat workflow. Example sendChatMessage input (the sample must already be ready):
For an existing recording, use the authorized MEDIA identity returned by the asset picker. Keep that identity; do not substitute its temporary playback URL. Incomplete input returns to the existing Chat input step. Continue with answerChatRun, using the current interruptId and baseVersion. Schema uiHints.modelConstraints contains advisory used, maximum, remaining, and privateAllowed values. Permissions, quota, concurrency, and sample availability are checked again at submission. The current native creation and internal preview use a 0 Credit quote. Explicit confirmation is still required because creation occupies a model slot and starts preview generation. Submit confirmChatPlan with the exact planId, version, and quoteId from the current card and a unique clientRequestId. Edits require a new quote and confirmation. Repeated confirmation or a lost response must reuse the original submission; inspect its status instead of starting another model. The accepted result carries resourceType: "MODEL" and modelId. Completion waits for the preview, not just reference upload. A successful output includes type: "AUDIO", modelUsage: "VOICE", name, description, isPublic, viewUrl, and playbackUrl. There is no synthetic mediaId. Playback URLs expire and should be refreshed through an authorized result read. Failed or incomplete models are not selectable as ready voices. After completion, find the voice through chatVoiceModels(source: "PERSONAL"). Follow-up actions create a new draft for Generate Audio, Talking Avatar, or Lip Sync using voiceModelId and audioInputMode: "VOICE_SCRIPT". They do not submit generation automatically; the remaining script and visual inputs still need to be supplied and validated.