Current public API surface

Pamba API Docs

Build agent-driven workflows for AI avatar videos, TikTok research, video generation, scheduling, warming, and analytics with workspace-scoped API keys.

Authentication

Agents authenticate with X-API-Key. JWT callers include X-Workspace-Id on workspace routes.

Workspace-Scoped

API keys are tied to one workspace, so agents can create content, manage avatars, schedule posts, and pull analytics for that workspace.

Base URL

Use https://api.pamba.app. All content production routes require authentication.

Bulk project creation accepts date-only scheduling, such as 2026-05-18. Single post scheduling accepts date-only or ISO 8601 with timezone.

Credit Usage

Generation features are credit-metered: video clips, avatar photos, scene images, voices, and hook purchases. A user's very first avatar is free - its photos, scenes, and basic voice are not charged (premium voice still is). Fetch the current price list from GET /usage/pricing (public, no auth).

AI clip generation

POST /projects/{projectId}/generate-clip-videos, plus automated pipelines started from bulk project creation or automation restart/resume.

Per-model credits x generated video seconds - current per-model rates come from GET /usage/pricing. Credits are reserved for requested duration, then only successful generated clip seconds are charged.

Avatar photo generation

POST /avatars/generations, POST /avatars/projects/{projectId}/chat/async whenever the avatar agent generates or edits an appearance image, and the avatar wizard appearance pass.

15 credits per generated image. Failed generations are not charged.

Scene generation

POST /avatars/projects/{projectId}/selected-avatar/starting-frames and .../starting-frames/generations, plus starter scenes auto-populated by avatar creation and the avatar wizard.

15 credits per generated image. Bulk jobs reserve avatars x references x results upfront and charge only successfully generated images; uploads of your own frames are free.

Voice generation

Avatar creation/update chat whenever a new voice is designed, POST /avatars/projects/raw, PATCH /avatars/projects/{projectId} when selecting an avatar without a voice, and keeping a basic voice in the avatar wizard. Wizard voice previews are free to audition.

100 credits per voice. Charged once per created voice; reusing an avatar's existing voice is free.

Premium voice generation

Avatar chat with video_model_based_voice_creation, the toggle-only premium voice regeneration, and premium options in the avatar wizard (charged per clone generated).

1500 credits per voice clone. Covers the video-model speaking clips the voice is cloned from; the interim designed voice it replaces is not charged.

Hook video purchase

POST /hooks/purchase.

200 credits per hook. Already-purchased hooks are not re-charged.

Project creation, idea/script work, TikTok research/analytics, frame uploads and management, scheduling, warming, rendering existing edits, and editor-state saves are not separately credit-metered in the public API today. Metered endpoints respond 402 { error, remaining_credits, required_credits } when the balance is too low, and failed operations are never charged. Use GET /user to inspect subscription state and credit totals/usage.

What Agents Can Do

Track competitor accounts, filter their best videos, create ideas, remix scripts, and start projects.

Bulk-create fully automated projects that generate clips, render, schedule, and post.

Manually drive a project through concept, clip generation, selected takes, render, and scheduling.

Configure avatar warming and monitor session status.

Pull TikTok analytics dashboards, tracked account metrics, and per-video history.

Public Endpoint Reference

Account

Read caller profile, subscription state, and credit totals.

GET/user

Current user profile, subscription state, and credit totals/usage.

Authentication

X-API-Key or JWT. JWT callers do not need X-Workspace-Id on this bootstrap route.

Request

No body.

Response

200 { total_paid_monthly_credits, used_paid_monthly_credits, total_coupon_credits, used_coupon_credits, unlimited_credits, subscribed_product_name, subscription_status, email, email_verified, success, message }. When unlimited_credits is true, credits are not enforced for this user in this workspace and the credit fields are not a meaningful balance.

Ideas and Scripts

Create content concepts, remix scripts, and link avatars. To start a project from a script, pass the script to POST /projects.

GET/ideas

List ideas with pagination, filters, sorting, and archived state.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Query page, page_size, sort_by, sort_direction, archived, min_views, max_views, min_views_per_follower, max_views_per_follower, min_engagement_rate, max_engagement_rate, days_lookback, phone_number, search.

Response

200 { ideas: Idea[], page, page_size }; Idea includes id, title, notes, status, analyzed_video, scripts, avatars, video_projects, archived_at, created_at.
POST/ideas

Bulk-create ideas from titles, notes, and TikTok URLs.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

JSON body { "ideas": [{ "title"?, "tiktok_video_url"?, "notes"? }] }.

Response

201 { idea_ids: string[] }.

Example

curl -X POST https://api.pamba.app/ideas \
  -H "X-API-Key: $PAMBA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "ideas": [{ "title": "Before/after plumbing POV", "notes": "Make it punchy" }] }'
PUT/ideas

Bulk-update ideas.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

JSON body { "ideas": [{ "idea_id": UUID, "notes"?, "tiktok_video_url"?, "archived"? }] }.

Response

200 { updated_count: number }.
PUT/ideas/{id}

Update notes, TikTok URL, or archived state for one idea.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { id: UUID }; JSON body { "notes"?, "tiktok_video_url"?, "archived"? }.

Response

200 { success: true }.
POST/ideas/{id}/branch

Branch an idea into a new variant.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { id: UUID }; JSON body { "new_title": string, "notes"?: string }.

Response

201 { idea_id: UUID }.
POST/ideas/{id}/avatars

Attach avatars to an idea.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { id: UUID }; JSON body { "avatar_project_ids": UUID[] }.

Response

200 { success: true }.
DELETE/ideas/{id}/avatars

Remove avatars from an idea.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { id: UUID }; JSON body { "avatar_project_ids": UUID[] }.

Response

200 { success: true }.
POST/ideas/scripts

Create a script for an idea.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

JSON body { "idea_id": UUID, "content": string }.

Response

201 { script_id: UUID }.
POST/ideas/scripts/remix

Generate script variations from an idea.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

JSON body { "idea_id": UUID, "custom_prompt"?: string }.

Response

201 { script_id: UUID }.
PUT/ideas/scripts/{id}

Update script content.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { id: UUID }; JSON body { "content": string }.

Response

200 { success: true }.
DELETE/ideas/scripts/{id}

Delete a script.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { id: UUID }; no body.

Response

200 { success: true }.
POST/ideas/scripts/{id}/avatars

Attach avatars to a script.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { id: UUID }; JSON body { "avatar_project_ids": UUID[] }.

Response

200 { success: true }.
DELETE/ideas/scripts/{id}/avatars

Remove avatars from a script.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { id: UUID }; JSON body { "avatar_project_ids": UUID[] }.

Response

200 { success: true }.

TikTok Research and Analytics

Track accounts, inspect analyzed videos, and pull dashboard metrics.

POST/tiktok/tracked-accounts

Track TikTok usernames for research.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

JSON body { "usernames": string[] }.

Response

201 { account_ids: UUID[] }.

Example

curl -X POST https://api.pamba.app/tiktok/tracked-accounts \
  -H "X-API-Key: $PAMBA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "usernames": ["competitor_handle"] }'
GET/tiktok/tracked-accounts

List tracked accounts and avatar links.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

No body.

Response

200 { accounts: TrackedAccount[] }; includes username, follower_count, status, avatar_id, avatar_name, deactivation_reason.
DELETE/tiktok/tracked-accounts/{username}

Stop tracking an account.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { username: string }; no body.

Response

200 { success: true }; 409 if the account is linked to an avatar.
GET/tiktok/tracked-accounts/{username}/fetch-status

Check initial fetch status.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { username: string }; no body.

Response

200 { username, status }.
GET/tiktok/tracked-accounts/videos

List analyzed videos with username and performance filters.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Query page, page_size, username, sort_by, sort_direction, min_views, max_views, min_views_per_follower, max_views_per_follower, min_engagement_rate, max_engagement_rate, days_lookback, search, include_research_accounts.

Response

200 { videos: TrackedVideo[], page, page_size }; video includes metrics, transcript, summary, idea_id, analysis fields.
GET/tiktok/tracked-accounts/{username}/views-per-day

Daily views, likes, comments, shares, and bookmarks.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { username }; query days 1-365, timezone.

Response

200 { username, days: [{ date, views, likes, comments, shares, bookmarks }] }.
GET/tiktok/tracked-accounts/{username}/metrics

Read account-level aggregates.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { username }; no body.

Response

200 aggregate metrics including video_count, total_views, average metrics, engagement rate, duration and posting cadence.
GET/tiktok/tracked-accounts/{username}/metrics-history

Per-video metric snapshots over time.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { username }; no body.

Response

200 { username, videos: [{ tiktok_video_id, title, description, author_username, snapshots[] }] }.
GET/tiktok/analytics/accounts

Accounts available in analytics.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

No body.

Response

200 { accounts: [{ username }] }.
GET/tiktok/analytics/dashboard

Fetch trends, top videos, and recent videos.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Query days 1-365, timezone.

Response

200 dashboard data with current/previous totals, trend series, top videos and recent videos for every avatar account in the workspace.

Avatars and Starting Frames

Manage speaker personas and the images that keep videos visually consistent.

GET/avatars

List avatars by status or tag.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Query avatar_status, tag.

Response

200 Avatar[]; includes id, project_id, name, status, tags, TikTok accounts, image/voice metadata and warming config.
POST/avatars/projects

Create a draft avatar project.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

No body.

Response

201 { project_id: UUID }.
POST/avatars/projects/raw

Create an avatar from multipart form data and a reference image.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

multipart/form-data: name, gender=MALE|FEMALE, image file; optional accent, base_appearance_description, adaptive_appearance_description, background_description, speaker_description.

Response

201 { avatar_id, project_id, name, gender, image_url, voice_id, voice_sample_url }; 402 { error, remaining_credits, required_credits } on insufficient credits.
GET/avatars/projects/{projectId}

Get an avatar project.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

200 avatar project details including selected avatar and generated candidates.
PATCH/avatars/projects/{projectId}

Select an avatar for an avatar project.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "selected_avatar_id": UUID }.

Response

200 OK; 402 { error, remaining_credits, required_credits } on insufficient credits.
DELETE/avatars/projects/{projectId}

Delete an avatar project.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

204 No Content.
PUT/avatars/projects/{projectId}/selected-avatar

Update selected avatar tags, TikTok usernames, status, and warming config.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "avatar_status"?, "tiktok_usernames"?, "tags"?, "warming_search_terms"?, "warming_config"? }. Warming is always on; warming_search_terms sets only the browse search terms (empty array reverts to the workspace's auto niche terms), warming_config sets scheduling anchors.

Response

200 OK.
PUT/avatars/projects/{projectId}/selected-avatar/tiktok-accounts/{username}

Update status for a linked TikTok account.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID, username: string }; JSON body { "status": string }.

Response

200 OK.
POST/avatars/projects/{projectId}/chat

Chat with the avatar creator.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body either { "user_input": string } or { "structured_message": { name, gender, base_appearance_description, adaptive_appearance_description, background_description, voice_description } }.

Response

200 avatar chat response with generated avatar/project state.
GET/avatars/projects/{projectId}/selected-avatar/starting-frames

List selected-avatar scenes for an avatar project.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

200 AvatarFrame[]; frame has id, image_url, is_active, camera_style, tags, created_at, is_profile_image.
POST/avatars/projects/{projectId}/selected-avatar/starting-frames

Generate selected-avatar scenes from a prompt.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "prompt": string, "count": 1-10, "camera_style": string, "tags": string[] }.

Response

200 AvatarFrame[]; 402 { error, remaining_credits, required_credits } on insufficient credits.
POST/avatars/projects/{projectId}/selected-avatar/starting-frames/generations

Start a bulk scene generation job for the selected avatar.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "rows": [{ tiktok_url, camera_style, tags?, cover_url? }], "results_per_ref": 2-6 }.

Response

202 BulkGenerationJob { id, status, avatar_count, video_count, total_combinations, results_per_combo, completed_count, failed_count, created_at }; 402 { error, remaining_credits, required_credits } on insufficient credits.
POST/avatars/projects/{projectId}/selected-avatar/starting-frames/upload

Upload a selected-avatar scene image.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

multipart/form-data: image file, camera_style, optional comma-separated tags.

Response

200 AvatarFrame.
PUT/avatars/projects/{projectId}/selected-avatar/starting-frames/profile

Set a selected-avatar scene as profile image.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "frame_id": UUID }.

Response

200 OK.
PATCH/avatars/starting-frames/{frameId}

Update a frame's active state, camera style, or tags.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { frameId: UUID }; JSON body any of { "active": boolean, "camera_style": string, "tags": string[] }.

Response

200 OK.
DELETE/avatars/starting-frames/{frameId}

Delete one starting frame.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { frameId: UUID }; no body.

Response

204 No Content; 409 when deleting the profile image.
DELETE/avatars/starting-frames

Bulk-delete starting frames.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

JSON body { "frame_ids": UUID[] }.

Response

204 No Content.
GET/avatars/starting-frames/reference-frames

List reference frames, optionally by tag.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Optional query tag.

Response

200 ReferenceFrame[] for golden/reference frames.

Projects and Generation

Create fully automated batches or control each generation step manually.

POST/projects

Bulk-create projects, including fully automated projects.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

JSON body { "projects": [{ "selected_avatar_project_id": UUID, "script"?, "idea_description"?, "notes"?, "project_name"?, "is_fully_automated"?, "camera_style"?, "bullet_list"?, "scheduled_at"?, "video_description"?, "tiktok_username"?, "keep_tiktok_song"?, "only_create_draft"?, "reference_video_url"?, "video_model"?, "keep_raw_voice"?, "generate_video"? }] }. The "script" is stored directly as the creative concept (deterministic script→clips split, no agent); required for is_fully_automated. "idea_description" is the alternative to script - the server writes a distinct script from it per project ("idea_variation"/"idea_variation_count" optionally carry the numbering when one idea fans out across separate requests). "generate_video": true generates and renders the video right after creation (non-automated projects with a script or idea only).

Response

201 { project_ids: UUID[] }.

Notes

If is_fully_automated is true, automation may later consume credits during clip generation. generate_video consumes video credits immediately.

Example

curl -X POST https://api.pamba.app/projects \
  -H "X-API-Key: $PAMBA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "projects": [{
      "selected_avatar_project_id": "$AVATAR_PROJECT_ID",
      "project_name": "Plumber POV #1",
      "script": "Day in the life of a plumber. First call at 7am, a flooded basement. By noon I found a ring the customer lost years ago.",
      "is_fully_automated": true,
      "video_description": "Day in the life #plumbing",
      "tiktok_username": "plumber_pov",
      "scheduled_at": "2026-05-18"
    }]
  }'
POST/projects/create

Create one blank project for an avatar.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

JSON body { "selected_avatar_project_id": UUID }.

Response

200 Project { project, messages }.
GET/projects

List projects.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

No body.

Response

200 VideoProject[].
GET/projects/{projectId}

Get one project plus chat messages.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

200 Project { project, messages }.
PATCH/projects/{projectId}

Update metadata, states, notes, selected concept, reference URL, or automation config.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body any of { "project_name"?, "user_visibility"?, "posted_state"?, "user_review_state"?, "notes"?, "reference_video_url"?, "full_automation_configuration"? }.

Response

200 updated project.
PATCH/projects

Bulk-update project states and notes.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

JSON body { "updates": [{ "project_id": UUID, "user_visibility"?, "posted_state"?, "user_review_state"?, "notes"? }] }.

Response

200 { success: true }.
POST/projects/{projectId}/duplicate-shallow-concept

Duplicate a project's shallow concept.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

201 Project { project, messages }.
POST/projects/{projectId}/selected-creative-concept

Set speaker, background, script, and clips for the selected concept.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "speaker_description": string, "background_description": string, "clips"?, "script"?, "starting_frame_for_all_clips_url"? }.

Response

200 updated selected creative concept.
GET/projects/{projectId}/creative-concepts

List the project's creative concept version history, newest first.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

200 { "versions": [{ "id", "created_at", "is_selected", "speaker_description", "background_description", "script"?, "clips" }] } newest first.
POST/projects/{projectId}/creative-concepts/{conceptId}/select

Revert the project to a prior concept version.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID, conceptId: UUID }; no body.

Response

200 on revert to that concept version; 404 when the concept doesn't belong to the project.
POST/projects/{projectId}/generate-starting-frames

Generate project-level starting frames.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "camera_style": string }.

Response

200 generated project-level starting frames.
POST/projects/{projectId}/upload-starting-frame

Upload a project-level starting frame image.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

multipart/form-data: image file, camera_style, and optional persist_to_avatar_library (boolean, default false - when true the scene is also saved to the avatar's active library).

Response

200 uploaded starting frame.
DELETE/projects/{projectId}/starting-frames

Delete project-level starting frames.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "frame_ids": UUID[] }.

Response

200 OK.
POST/projects/{projectId}/edited-video

Upload a finished edited video.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

multipart/form-data with video file, or JSON/body containing an existing video URL depending on client flow.

Response

200 { "edited_video_url": string }.
POST/projects/{projectId}/generate-clip-videos

Generate selected clip indexes.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "clips_to_generate": [{ "index": number, "starting_frame_url"?: string }] }.

Response

200 generation result; 402 { error, remaining_credits, required_credits }; 429 { error, pending_count }.

Notes

Costs per-model video credits x successfully generated video seconds - current per-model rates come from GET /usage/pricing. On a replication DRAFT project, the settle of a full generation triggers a server-side final edit: automation_state flips to running for the edit's duration (editor-state writes 409 in that window) and editor_state is rewritten when it completes - wait for automation_state to leave running before editing, rendering or scheduling.

Example

curl -X POST https://api.pamba.app/projects/$PROJECT_ID/generate-clip-videos \
  -H "X-API-Key: $PAMBA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "clips_to_generate": [{ "index": 0 }] }'
GET/projects/{projectId}/clips/{creativeConceptId}

Poll clip status for a creative concept.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID, creativeConceptId: UUID }; no body.

Response

200 { clips: [{ clip_id, position, script, duration_seconds, video_url, generation_status }] }.
GET/projects/{projectId}/video-generations

Get all generation history for a project.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

200 { clips: ClipVideoGenerationHistory[] }.
GET/projects/{projectId}/clips/{clipId}/video-generations

Get take history for one clip.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID, clipId: UUID }; no body.

Response

200 VideoGeneration[] for the clip.
PATCH/projects/{projectId}/clips/{clipId}

Select a take for a clip.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID, clipId: UUID }; JSON body { "selected_video_generation_id": UUID }.

Response

200 selection message, or 404 when clip/generation is not found.
POST/projects/{projectId}/render-full-video

Render the current project into a finished video.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

200 render result with output video URL/status.
POST/projects/{projectId}/resume-automation

Resume automation for a project.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

200 { "message": "Automation resumed" }.
POST/projects/{projectId}/restart-automation

Restart automation for a project.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

200 { "message": "Automation restarted" }.
POST/projects/{projectId}/automation/apply-clips

Apply generated clips in an automation pipeline.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

200 { "message": "Apply-clips pipeline started" }.
PATCH/projects/{projectId}/editor-state

Save editor state without rendering.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "editor_state": { "main_video_track": [{ "clip_id": UUID, "in_point"?: number, "out_point"?: number, "type"?: string }] } }.

Response

204 No Content.
POST/projects/{projectId}/render

Save editor state and start a background render job (202 + RenderJob; 409 if one is already running).

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body { "editor_state": { "main_video_track": [...] } }.

Response

202 RenderJob { id, project_id, status: "RUNNING", stitched_video_url, edited_video_url, error_message, created_at, completed_at } when a new render starts. 409 RenderJob when one is already running for the project (attach to it and poll; renders cannot be cancelled - the pipeline supersedes stale ones itself). Poll GET /projects/{projectId}/render-jobs/{jobId} (or .../render-jobs/latest) until status is COMPLETED, then read stitched_video_url/edited_video_url.
GET/projects/{projectId}/render-jobs/latest

Latest render job for the project (404 if never rendered).

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; no body.

Response

200 RenderJob for the project's most recent render, or 404 if it has never been rendered.
GET/projects/{projectId}/render-jobs/{jobId}

Poll a render job's status until COMPLETED.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID, jobId: UUID }; no body.

Response

200 RenderJob with the current status and (when COMPLETED) the output URLs.
POST/projects/{projectId}/schedule

Schedule a project to TikTok with JSON or multipart upload.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; JSON body or multipart: { "tiktok_username": string, "caption": string, "scheduled_at": string, "privacy"?, "keep_tiktok_song"?, "only_create_draft"?, "video_url"?, "automate"?, "bullet_list"? }.

Response

200 ScheduledPost.
GET/projects/{projectId}/video-generation-updates

SSE stream for generation updates.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; SSE request.

Response

text/event-stream with video generation update events.
GET/projects/agent-state-updates

SSE stream for project automation lifecycle updates.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

SSE request; optional project filters may be added by the client.

Response

text/event-stream with project_id, creation_stage, activity_state, posted_state, user_review_state, automation_state, selected_creative_concept, scheduled_post.

Streaming

Subscribe to project status events.

GET/stream/status/{projectId}

SSE status stream for project generation.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { projectId: UUID }; SSE request.

Response

text/event-stream status updates for project generation.

Scheduling and Warming

Operate TikTok post queues and pre-post account warming.

GET/devices/tiktok/posts/scheduled

List scheduled posts by page or date range.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Query mode: page/page_size, or date range from, to, status, max. Optional username/project filters.

Response

200 { posts: ScheduledPost[], total, truncated? }.
GET/devices/tiktok/posts/{postId}

Get one scheduled post.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { postId: UUID }; no body.

Response

200 ScheduledPost.
PUT/devices/tiktok/posts/{postId}

Edit timing, caption, privacy, video URL, username, or failed-post dismissal.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { postId: UUID }; JSON body any of { "is_soft_deleted"?, "scheduled_at"?, "caption"?, "privacy"?, "keep_tiktok_song"?, "only_create_draft"?, "video_url"?, "tiktok_username"? }.

Response

200 ScheduledPost.
DELETE/devices/tiktok/posts/{postId}

Cancel a pending post. Optionally archive the project too.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { postId: UUID }; optional query archive_project=true.

Response

200 { success: true }.
POST/devices/tiktok/posts/{postId}/retry

Retry a failed post.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { postId: UUID }; no body.

Response

200 ScheduledPost.
GET/devices/tiktok/warming/config/avatar-projects/{avatarProjectId}

Read warming config for an avatar project.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { avatarProjectId: UUID }; no body.

Response

200 { enabled, status, total_minutes_daily_anchor, session_count_daily_anchor, search_terms, error_message }.
GET/devices/tiktok/warming/sessions

List warming sessions.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Query page/page_size/status/date filters depending on client flow.

Response

200 { sessions: WarmingSession[], total }.
GET/devices/tiktok/warming/sessions/{sessionId}

Get one warming session status/detail.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { sessionId: UUID }; no body.

Response

200 WarmingSession status/details.
DELETE/devices/tiktok/warming/sessions/{sessionId}

Cancel a pending warming session.

Authentication

X-API-Key, or JWT + X-Workspace-Id for workspace-scoped routes.

Request

Path { sessionId: UUID }; no body.

Response

200 { success: true }.

Billing

Stripe checkout/portal sessions and the public credit price list.

POST/billing/create-stripe-checkout-session

Create a Stripe checkout session.

Authentication

X-API-Key or JWT. JWT callers do not need X-Workspace-Id on this bootstrap route.

Request

JSON body { "price_id": string }.

Response

200 { "session_url": string }.
POST/billing/create-customer-portal-session

Create a Stripe customer portal session.

Authentication

X-API-Key or JWT. JWT callers do not need X-Workspace-Id on this bootstrap route.

Request

No body.

Response

200 { "portal_url": string }.
GET/usage/pricing

Public credit price list for all metered operations.

Authentication

Public. No authentication required.

Request

No body.

Response

200 { "video_generation_credits_per_second_by_model": { "xai/grok-imagine-video-1.5": 10.4, "bytedance/seedance-2.0/image-to-video": 48.1, "gemini-omni-flash-preview": 16.9 }, "video_generation_credits_per_second": 60, "photo_generation_credits_per_image": 15, "scene_generation_credits_per_image": 15, "basic_voice_generation_credits": 100, "premium_voice_generation_credits": 1500, "hook_video_purchase_credits": 200 }.

Notes

Values are the live backend constants; clients should read prices from here instead of hardcoding.

Fast Start

Create a project batch with an avatar and let automation handle generation, render, and scheduling.

curl -X POST https://api.pamba.app/projects \
  -H "X-API-Key: $PAMBA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "projects": [{
      "selected_avatar_project_id": "$AVATAR_PROJECT_ID",
      "project_name": "Plumber POV #1",
      "script": "Day in the life of a plumber. First call at 7am, a flooded basement. By noon I found a ring the customer lost years ago.",
      "is_fully_automated": true,
      "video_description": "Day in the life #plumbing",
      "tiktok_username": "plumber_pov",
      "scheduled_at": "2026-05-18"
    }]
  }'