GraphQLThis is the API the app itself runs on, at /graphql. The REST API is a thin layer over it — every REST endpoint runs one of these operations — so this is the full picture of what Snoobl can do.
GraphQL runs on your signed-in session, not an API key. Building a server integration? Use the REST API — that's what keys are for. The sandbox below runs as you.
Sandbox
Query
Variables (JSON)
Runs as you, against the live API. Mutations are real.
Schema reference
Search the schema
queries
accountDeletionBlockers[AccountDeletionBlocker!]!
Workspaces the viewer must hand over (or empty) before deleting their account.
apiKeys(workspaceId: ID!)[ApiKey!]!
A workspace's API keys, newest first (owner/admin only).
billingPortalUrl(workspaceId: ID!)BillingPortalPayload!
A Stripe Customer Portal URL for managing the saved payment method.
brand(id: ID!)Brand
A single brand by id (requires access to its workspace).
brands(after: String, first: Int, workspaceId: ID!)BrandConnection!
Brands in a workspace the viewer can access (Relay connection, newest first).
contextItems(after: String, brandId: ID!, first: Int)ContextItemConnection!
Context items for a brand (Relay connection, newest first).
creditBalance(workspaceId: ID!)CreditBalance!
Current shared credit balance for a workspace.
creditCosts[CreditCost!]!
The public credit-cost table (powers the CreditExplainer everywhere).
creditLedger(after: String, first: Int, workspaceId: ID!)CreditLedgerConnection!
Paginated credit ledger for a workspace (newest first).
creditPacks[CreditPack!]!
Active one-time credit packs (seeded launch defaults for now).
editTools[EditTool!]!
The edit stack's per-job tool status. Drives the RefineModal's honesty UI: the pre-confirm "comes back at 720p" warning when a lower-ceiling tool is enabled, and the per-tool "unavailable" state (zero charge, no substitute).
filmBySlug(slug: String!)PublicFilm
Public viewer lookup by share-link slug — no auth. Plays the take on `(marketing)/v/[slug]`. Null when the slug is unknown or revoked.
invitePreview(token: String!)InvitePreview
Looks up an invite by its emailed token (no auth — the token is the credential).
meUser
The currently authenticated user, or null.
myWorkspaces[Workspace!]!
Workspaces the viewer belongs to (anonymous sessions see their provisional one).
notificationPreferencesNotificationPreferences!
The viewer's notification preferences.
project(id: ID!)Project
A single project by id (requires access to its brand's workspace).
projects(after: String, brandId: ID!, first: Int)ProjectConnection!
Projects in a brand the viewer can access (Relay connection, newest first).
showcaseFilms(after: String, first: Int)ShowcaseFilmConnection!
Public showcase films for the landing-page video wall (real opted-in takes, seeded fallback).
take(id: ID!)Take
A single take by id (requires access to its project's workspace).
takes(after: String, first: Int, projectId: ID!)TakeConnection!
A project's rendered takes (Relay connection, newest first).
videoProviders[ProviderStatus!]!
Every configured video provider row with live cost + circuit-breaker health. Debug/admin: platform admins anywhere, any signed-in viewer on non-production environments.
webhookEndpoints(workspaceId: ID!)[WebhookEndpoint!]!
A workspace's webhook endpoints, newest first (owner/admin, or a manage-scope key).
workspace(id: ID!)Workspace
A single workspace by id (requires access).
workspaceInvites(after: String, first: Int, workspaceId: ID!)WorkspaceInviteConnection!
Pending invites for a workspace, newest first (owner/admin only).
mutations
acceptInvite(input: AcceptInviteInput!)Workspace!
Accepts a workspace invite for the authenticated viewer (whose email must match the invite) and makes that workspace their active one. Joining only grants access to the workspace's shared credit pool — no credits are minted.
addBrandAsset(input: AddBrandAssetInput!)BrandAsset!
Records an uploaded brand asset against a brand.
addContextItem(input: AddContextItemInput!)ContextItem!
Adds a context item (upload key / URL / note) to a brand. Moderates URL/note text.
addReferenceImage(input: AddReferenceImageInput!)ReferenceImage!
Attaches a product reference image (max 9) from an upload key or an existing image context item. References keep the real product accurate in renders.
analyzeBrand(brandId: ID!)Brand!
Starts analyzing a brand's context into a BrandProfile and returns straight away — the work runs as a background job (a minute or two). Poll Brand.latestAnalysisJob until it is completed or failed; a completed run has saved a new active profile version. Calling it while a run is already going joins that run instead of starting another.
blendTakes(adjustment: String, takeIdA: ID!, takeIdB: ID!)Take!
Merges two completed takes' prompts into one new take (async). A blend is a full render at the first take's settings and is priced as one.
claimAnonymousWorkspaceWorkspace
Claims the signed-in viewer's still-present anonymous session (the `anon_session` cookie / anon Bearer alongside their auth): a first-time convert ADOPTS the provisional workspace as their personal one (free grant applied to it), a returning user has its brands/projects MERGED into their existing personal workspace. Normally this happens automatically inside the sign-in/up mutations — this is the explicit rescue path. Returns the workspace that now holds the work, or null when there was nothing to claim.
createAnonymousSessionAnonymousSessionPayload!
Issues an anonymous-session JWT for pre-auth session tracking.
createApiKey(input: CreateApiKeyInput!)CreateApiKeyPayload!
Creates an API key and returns it ONCE (owner/admin only).
createBrand(input: CreateBrandInput!)Brand!
Creates a brand in a workspace (members + anonymous provisional owners).
createCheckoutSession(packId: ID!, platform: CheckoutPlatform!, workspaceId: ID!)CheckoutSession!
Starts a credit-pack purchase. `stripe` → a Stripe Checkout URL (web/Android); `apple` → the pack's Apple product id (the client drives the IAP sheet, then calls `verifyApplePurchase`). Owner/admin only.
createProject(input: CreateProjectInput!)Project!
Creates a project in a brand (members + anonymous provisional owners).
createShareLink(takeId: ID!)ShareLink!
Mints a revocable public share link for a completed take (the /v/[slug] viewer). Generates an unguessable slug and sets `enabled`. Idempotent: if an enabled link already exists, returns it; a revoked one is re-enabled with a fresh slug. Requires write access to the take's project.
createUploadUrl(contentType: String!, filename: String!)UploadTarget!
Returns a presigned URL for a direct upload to the user's namespace.
createWebhookEndpoint(input: CreateWebhookEndpointInput!)WebhookEndpoint!
Registers a webhook endpoint (owner/admin, or a manage-scope key).
createWorkspace(input: CreateWorkspaceInput!)Workspace!
Creates a new (non-personal) workspace owned by the viewer.
deleteBrand(brandId: ID!)Boolean!
Deletes a brand and its assets (owner/admin, or the anonymous provisional owner).
deleteMyAccount(input: DeleteMyAccountInput!)Boolean!
Permanently deletes the viewer's account: workspaces only they are in go with it (brands, films, credits); they're removed from shared ones. Refused while they're the only owner of a workspace other people are still on.
deleteProject(projectId: ID!)Boolean!
Deletes a project and its storyboard versions.
deleteWebhookEndpoint(id: ID!)Boolean!
Removes a webhook endpoint and its delivery history.
exportMyDataAccountExport!
Builds a JSON export of everything Snoobl holds about the viewer.
generateStoryboard(input: GenerateStoryboardInput!)Job!
Kicks off a storyboard generation as an async job (the Director's OpenAI calls are slow — never a long sync request). Persists any provided controls onto the project first. When versions already exist this produces a fresh divergent concept, like regenerateStoryboard.
generateTakes(input: GenerateTakesInput!)[Take!]!
Renders takes of a locked storyboard version (async jobs; poll `takes`). Debits the credits up front — failed renders auto-refund. Requires a signed-in member who may spend (the Generate sign-in gate for anonymous viewers): role, per-member limit, monthly cap, balance and the workspace render-concurrency cap are all checked before anything is queued.
inviteMember(input: InviteMemberInput!)WorkspaceInvite!
Invites a member by email (owner/admin only) and emails them the accept link.
leaveWorkspace(workspaceId: ID!)Boolean!
Leaves a workspace the viewer is a member of (the last owner can't leave).
refineTake(input: RefineTakeInput!)Take!
Surgically edits a completed take (async — returns the new edit-revision take, queued). Costs 25% of the take's render cost (min 0.25 credits), debited up front and auto-refunded on failure. The edit runs on the ONE enabled frontier model for its job — if that tool is down, this mutation fails honestly BEFORE any debit; no other model is ever substituted. Chain refinements by refining an edited take ("keep refining", re-priced by the same 25% rule).
refreshAccessToken(refreshToken: String)AuthPayload!
regenerateStoryboard(input: GenerateStoryboardInput!)Job!
Regenerates the storyboard as a fresh, divergent concept (async job), persisting any provided controls first. The Director chat is cleared — it was about the previous concept.
registerSsoInterest(input: RegisterSsoInterestInput!)SsoInterest!
Registers a workspace's interest in SSO / SAML and tells the Snoobl team.
remixProject(projectId: ID!)Project!
Clones a project's creative recipe — brief, storyboard versions, reference images and settings — into a new editable project under the same brand. Rendered takes are NOT copied; the new project starts at the storyboard stage with `remixedFromProjectId` set.
removeContextItem(itemId: ID!)Boolean!
Removes a context item from a brand.
removeMember(memberId: ID!)Boolean!
Removes a member from a workspace (owner/admin only; admins can't remove owners).
removeReferenceImage(referenceImageId: ID!)Boolean!
Removes a reference image from a project.
requestMagicLink(email: String!)MagicLinkRequest!
Sends a single-use magic-link sign-in email (logged to the console in dev).
resendInvite(inviteId: ID!)WorkspaceInvite!
Re-sends a pending invite with a fresh link + expiry (owner/admin only).
retryTake(takeId: ID!)Take!
Re-submits a FAILED take with its exact recipe as a fresh take. The failed take already auto-refunded, so a retry never double-charges — the fresh debit is the only net charge.
revokeApiKey(id: ID!)ApiKey!
Revokes an API key — it stops working immediately (owner/admin only).
revokeInvite(inviteId: ID!)WorkspaceInvite!
Revokes a pending invite so its link stops working (owner/admin only).
revokeShareLink(takeId: ID!)ShareLink!
Revokes a take's public share link (the /v/[slug] URL then 404s). The row stays for audit; flip it back on with createShareLink. Requires write access to the take's project.
selectBrandProfileVersion(brandId: ID!, versionId: ID!)Brand!
Makes an earlier analysis version the brand's active profile.
selectTake(takeId: ID!)Take!
Marks a take as the project's picked favorite (clears its siblings).
selectVersion(projectId: ID!, versionId: ID!)Project!
Makes an earlier storyboard version the project's active one.
sendDirectorMessage(message: String!, projectId: ID!)Job!
Sends a Director-chat message: a SURGICAL edit of the current version (only what you ask changes), applied as an async job that appends a new version.
sendTestWebhook(endpointId: ID!)WebhookDelivery!
Sends a signed `webhook.test` event to the endpoint and reports how it went.
setAutoTopup(input: SetAutoTopupInput!)Workspace!
Turns auto top-up on/off and sets the threshold + pack (owner/admin only).
setMemberSpendLimit(input: SetMemberSpendLimitInput!)WorkspaceMember!
Sets a member's spend controls (owner/admin only).
setMonthlySpendCap(input: SetMonthlySpendCapInput!)Workspace!
Sets or clears the monthly auto-top-up spend cap (owner/admin only).
setNotificationPreferences(input: SetNotificationPreferencesInput!)NotificationPreferences!
Updates the viewer's notification preferences (only the fields passed).
setTakeShowcase(optIn: Boolean!, takeId: ID!)Take!
Opts a completed take into — or out of — the public homepage showcase. Opting in makes the film public on the landing 3D wall AND remixable by anyone (your brief + storyboard, not your account). Off by default; flip it back anytime. Requires write access to the take's project.
signIn(input: SignInInput!)AuthPayload!
signInWithApple(displayName: String, identityToken: String!)AuthPayload!
signInWithGoogle(idToken: String!)AuthPayload!
signInWithMagicLink(token: String!)AuthPayload!
signOut(refreshToken: String)Boolean!
signUp(input: SignUpInput!)AuthPayload!
switchWorkspace(workspaceId: ID!)Workspace!
Sets the viewer's active workspace (persisted in a cookie).
updateBrand(input: UpdateBrandInput!)Brand!
Updates a brand's editable fields (members + anonymous provisional owners).
updateMemberRole(input: UpdateMemberRoleInput!)WorkspaceMember!
Changes a member's role (owner/admin only).
updateProfile(input: UpdateProfileInput!)User!
Updates the viewer's display name.
updateProject(input: UpdateProjectInput!)Project!
Updates a project's editable fields (members + anonymous provisional owners).
updateWorkspace(input: UpdateWorkspaceInput!)Workspace!
Renames a workspace (owner/admin only).
verifyApplePurchase(productId: String!, transactionId: String!, workspaceId: ID!)VerifyApplePurchasePayload!
Verifies a finished Apple IAP purchase against the ledger (idempotent on the Apple transaction id). The client calls this after expo-iap's purchase flow.
AcceptInviteInput
input
tokenString!
AccountDeletionBlocker
object
A workspace standing in the way of account deletion: the viewer is its only owner and other people are still on it.
otherMemberCountInt!
workspaceIdID!
workspaceNameString!
AccountExport
object
A short-lived link to a JSON file of everything Snoobl holds about the viewer.
expiresAtDateTime!
filenameString!
urlString!
AddBrandAssetInput
input
brandIdID!
keyString!
The uploaded S3 object key (from `createUploadUrl`).
kindBrandAssetKind!
labelString
mimeTypeString
AddContextItemInput
input
brandIdID!
keyString
Uploaded S3 object key (for pdf/image/video/pptx/other uploads).
kindContextItemKind!
mimeTypeString
nameString!
Display name (file name, note title, or the URL).
sizeBytesInt
textString
Note body (for a text item).
urlString
External link (for a url item).
AddReferenceImageInput
input
fromContextItemIdID
Pull the image from one of the brand's analyzed context items instead.
keyString
Uploaded S3 object key (from `createUploadUrl`).
labelString
projectIdID!
AnonymousSessionPayload
object
sessionIdString!
tokenString!
ApiKey
object
A workspace API key for the public REST API and the MCP server. The key itself is only ever returned by `createApiKey`; afterwards just its `prefix` is known.
createdAtDateTime!
createdByEmailString
Email of whoever created the key (null if that account is gone).
idID!
lastUsedAtDateTime
nameString!
prefixString!
The first characters of the key (e.g. snbl_live_a1B2c3) — safe to show.
rateLimitPerMinInt!
revokedAtDateTime
scopes[ApiKeyScope!]!
workspaceIdID!
ApiKeyScope
enum
What an API key may do. Each scope implies the ones before it.
manage
read
render
AuthPayload
object
refreshTokenString!
tokenString!
userUser!
Beat
object
One storyboard beat — a shot within the single film.
audioCueString
cameraString
descriptionString!
indexInt!
onScreenTextString
titleString!
BillingPortalPayload
object
A Stripe Customer Portal URL for managing the saved payment method.
urlString!
103 more types — search to find them.
Your films are yours. Commercial use included — no asterisk.
© 2026 Snoobl · hello@snoobl.com