GraphQL API · Workspace API keys

PlentyLabs API

Drive the PlentyLabs creative platform from your own backend — read workspace & brand context, browse and manage the asset library, and generate & edit image, video, and audio. 55 operations, one endpoint, one bearer token — each with a ready-to-run document, because production introspection is off.

Endpoint https://api.plentylabs.com/graphql
Protocol GraphQL over HTTPS Auth Bearer API key 55 operations Scope One workspace

1 · Mint a key

Workspace owners only.

  1. In PlentyLabs Create: Settings → API keys.
  2. Name it, pick Read & write or Read only, set an expiry.
  3. Copy the plenty_sk_… token — it is shown once and is never recoverable.

2 · Ask for your workspace ID

Most operations take one. Don't go looking for it.

  1. Run GetWorkspace — it takes no arguments.
  2. Keep the id it returns; pass it wherever a workspaceId is asked for.
  3. Your key is pinned to that one workspace, so it is the only id that works — any other is refused.

3 · Call it

No cookies, no SDK, no handshake.

  1. POST to the endpoint above.
  2. Send Authorization: Bearer plenty_sk_….
  3. Copy a document from the catalog below — or take all 52.
  4. Or try it without writing anything: the playground, then the worked example.
Which workspace am I?query · start here
# Keep the key out of your shell history and out of the command itself.
export PLENTY_API_KEY=plenty_sk_…

# No arguments: the key already decides the answer. Keep the id.
curl https://api.plentylabs.com/graphql \
  -H "Authorization: Bearer $PLENTY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "query": "query GetWorkspace { apiCredentialWorkspace { id name } }" }'

# => { "data": { "apiCredentialWorkspace": { "id": "…", "name": "Acme" } } }
export PLENTY_WORKSPACE_ID=…
Browse the asset libraryquery
# Newest 5 images in the workspace.
curl https://api.plentylabs.com/graphql \
  -H "Authorization: Bearer $PLENTY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query($w:ID!){ assets(workspaceId:$w, first:5, filter:{types:[IMAGE]}){ edges{ node{ ... on Image { id displayName url } } } } }",
    "variables": { "w": "'"$PLENTY_WORKSPACE_ID"'" }
  }'
Generate, then collectmutation + poll
# Returns immediately with QUEUED rows. Keep the ids.
curl https://api.plentylabs.com/graphql \
  -H "Authorization: Bearer $PLENTY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation($w:ID!,$p:String!,$a:String!){ generateImage(workspaceId:$w, input:{prompt:$p, aspectRatio:$a, count:1}){ images{ id status } } }",
    "variables": { "w": "'"$PLENTY_WORKSPACE_ID"'", "p": "hero shot on seamless white", "a": "4:5" }
  }'

# Poll EACH id, backing off 5s, 10s, 15s, then 20s between every further
# attempt, until it is COMPLETED (downloadUrl set) or FAILED.
curl https://api.plentylabs.com/graphql \
  -H "Authorization: Bearer $PLENTY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query($id:ID!){ image(id:$id){ id status downloadUrl errorMessage } }",
    "variables": { "id": "ONE_OF_THE_IDS_ABOVE" }
  }'

# Do NOT pass sessionId to generateImage, and do not poll by it: that column
# is a foreign key onto a legacy table, nothing here can set it, and a board
# id there fails the whole mutation. A finished image is in the library and on
# no canvas — put it on a board with createCanvasCards.

Workspace & brand context

5 · read

The brand the output should stay on, and the credits it will spend.

Brand3
QbrandBooksThe Brand kits available in this workspace.
Show the ListBrandbooks call
query ListBrandbooks($workspaceId: ID!) {
  brandBooks(workspaceId: $workspaceId) {
    id
    name
    isConfigured
  }
}
QbrandBrand identity, tone of voice, and configuration state.
Show the GetBrand call
query GetBrand($workspaceId: ID!, $brandId: ID) {
  brand(workspaceId: $workspaceId, brandId: $brandId) {
    id
    name
    websiteUrl
    tagline
    companyDescription
    industry
    subindustry
    isConfigured
    defaultLogoId
    defaultFontId
    markets
    playbookBrand
    playbookCreative
    playbookPerformance
    playbookAnalyst
    playbookLocalization
    toneOfVoiceSections {
      title
      description
      kind
      values
    }
  }
  brandColors(workspaceId: $workspaceId, brandId: $brandId) {
    id
    name
    hex
    groupName
    usage
    role
  }
}
QbrandColorsThe palette by name and exact hex — weave both into generation prompts.
Show the GetBrand call
query GetBrand($workspaceId: ID!, $brandId: ID) {
  brand(workspaceId: $workspaceId, brandId: $brandId) {
    id
    name
    websiteUrl
    tagline
    companyDescription
    industry
    subindustry
    isConfigured
    defaultLogoId
    defaultFontId
    markets
    playbookBrand
    playbookCreative
    playbookPerformance
    playbookAnalyst
    playbookLocalization
    toneOfVoiceSections {
      title
      description
      kind
      values
    }
  }
  brandColors(workspaceId: $workspaceId, brandId: $brandId) {
    id
    name
    hex
    groupName
    usage
    role
  }
}
Identity1
QapiCredentialWorkspaceWhich workspace your key is scoped to. Call it first: it is where the workspaceId every other operation wants comes from, and it takes no arguments because the key already decides the answer.
Show the GetWorkspace call
query GetWorkspace {
  apiCredentialWorkspace {
    id
    name
  }
}
Credits1
QcreditsBalanceBalance, monthly allocation, and next refill — check before a large batch rather than discovering it as a failed generation.
Show the GetCredits call
query GetCredits($workspaceId: ID!) {
  creditsBalance(workspaceId: $workspaceId) {
    balance
    bonusBalance
    monthlyBalance
    monthlyAllocation
    isPaidPlan
    nextRefillAt
    daysUntilRefill
    dailyFree {
      remaining
      limit
      resetsAt
      monthlyRemaining
      monthlyLimit
      monthlyResetsAt
    }
  }
}

Boards & cards

15 · scope + arrange

The canvas a run belongs to, and everything on it. Pass a board's id as `sessionId` when you generate and the result opens in the app; address its cards by the board's `conversationId`.

Boards3
QstudioSessionsThe workspace's boards, most recently updated first.
Show the ListBoards call
query ListBoards($workspaceId: ID!) {
  studioSessions(workspaceId: $workspaceId) {
    id
    conversationId
    title
    coverUrl
    assetCount
    visibility
    viewerLevel
    starred
    createdAt
    updatedAt
  }
}
QstudioSessionOne board by id. Its `conversationId` is the canvas id every card call takes.
Show the GetBoard call
query GetBoard($id: ID!) {
  studioSession(id: $id) {
    id
    workspaceId
    conversationId
    title
    coverUrl
    assetCount
    visibility
    viewerLevel
    createdAt
    updatedAt
  }
}
McreateStudioSessionStart a board to generate into.
Show the CreateBoard call
mutation CreateBoard($workspaceId: ID!, $title: String, $visibility: StudioSessionVisibility) {
  createStudioSession(input: { workspaceId: $workspaceId, title: $title, visibility: $visibility }) {
    success
    session {
      id
      conversationId
      title
      visibility
      createdAt
    }
  }
}
Cards9
QcanvasCardsEverything on a board's canvas, with geometry and resolved assets. Removed cards are excluded unless you ask for them.
Show the ListCards call
query ListCards($conversationId: ID!, $includeRemoved: Boolean = false) {
  canvasCards(conversationId: $conversationId, includeRemoved: $includeRemoved) {
    id
    assetType
    assetId
    positionX
    positionY
    width
    height
    zIndex
    rotation
    text
    groupId
    sectionId
    removedAt
    style {
      fill
      textAlign
      textSize
    }
    asset {
      __typename
      ... on Image {
        id
        downloadUrl
        aspectRatio
        displayName
      }
      ... on Video {
        id
        downloadUrl
        thumbnailDownloadUrl
        aspectRatio
        displayName
      }
      ... on Audio {
        id
        downloadUrl
        durationMs
        audioName: name
      }
      ... on Product {
        id
        name
      }
      ... on Creative {
        id
        creativeName: name
        thumbnailUrl
      }
      ... on VideoSequence {
        id
        sequenceName: name
      }
    }
  }
}
QcanvasSectionsThe labelled rectangles that group cards into columns or stages. Read alongside the cards: a card's sectionId points at one of these, so cards alone lose the grouping. Read-only.
Show the ListSections call
query ListSections($conversationId: ID!) {
  canvasSections(conversationId: $conversationId) {
    id
    title
    positionX
    positionY
    width
    height
    color
    opacity
    shadow
    locked
    zOrdinal
    removedAt
  }
}
McreateCanvasCardPut one card on a board — an asset, a note, a shape or a connector. Omit width/height/position and the server sizes and places it the way the app does.
Show the PlaceCard call
mutation PlaceCard(
  $id: ID!
  $conversationId: ID!
  $workspaceId: ID!
  $assetType: String!
  $assetId: String!
  $origin: CanvasCardOrigin!
  $positionX: Float
  $positionY: Float
  $width: Float
  $height: Float
) {
  createCanvasCard(
    input: {
      id: $id
      conversationId: $conversationId
      workspaceId: $workspaceId
      assetType: $assetType
      assetId: $assetId
      origin: $origin
      positionX: $positionX
      positionY: $positionY
      width: $width
      height: $height
    }
  ) {
    success
    card {
      id
      assetType
      assetId
      positionX
      positionY
      width
      height
    }
  }
}
McreateCanvasCardsMany cards in one transaction. Omit every coordinate and the whole batch is laid out as one block on clear canvas.
Show the PlaceCards call
mutation PlaceCards($conversationId: ID!, $workspaceId: ID!, $cards: [CreateCanvasCardsEntryInput!]!) {
  createCanvasCards(input: { conversationId: $conversationId, workspaceId: $workspaceId, cards: $cards }) {
    success
    ids
  }
}
MupdateCanvasCardPositionMove and resize one card — position and size travel together.
Show the MoveCard call
mutation MoveCard(
  $conversationId: ID!
  $assetType: String!
  $assetId: String!
  $positionX: Float!
  $positionY: Float!
  $width: Float!
  $height: Float!
) {
  updateCanvasCardPosition(
    input: {
      conversationId: $conversationId
      assetType: $assetType
      assetId: $assetId
      positionX: $positionX
      positionY: $positionY
      width: $width
      height: $height
    }
  ) {
    success
  }
}
MbatchUpdateCanvasCardPositionsRelay out many cards in one write. Inserts a card it does not find, so check your ids.
Show the ArrangeCards call
mutation ArrangeCards($conversationId: ID!, $cards: [CanvasCardPositionEntry!]!) {
  batchUpdateCanvasCardPositions(input: { conversationId: $conversationId, cards: $cards }) {
    success
  }
}
MbatchUpdateCanvasCardZOrderRestack cards where they overlap. Existing cards only; z is fractional so you can slide one between two.
Show the RestackCards call
mutation RestackCards($conversationId: ID!, $entries: [CanvasCardZOrderEntry!]!) {
  batchUpdateCanvasCardZOrder(input: { conversationId: $conversationId, entries: $entries }) {
    success
  }
}
MdeleteCanvasCardTake a card off a board. A SOFT delete — the row survives with `removedAt` set, and the asset stays in the library.
Show the RemoveCard call
mutation RemoveCard($conversationId: ID!, $assetType: String!, $assetId: String!) {
  deleteCanvasCard(input: { conversationId: $conversationId, assetType: $assetType, assetId: $assetId }) {
    success
  }
}
MdeleteCanvasCardsTake a whole selection off in one write. Idempotent.
Show the RemoveCards call
mutation RemoveCards($conversationId: ID!, $entries: [CanvasCardGroupEntry!]!) {
  deleteCanvasCards(input: { conversationId: $conversationId, entries: $entries }) {
    success
  }
}
Notes & shapes3
MupdateCanvasCardTextRewrite a note's or prompt card's words. Replaces, never appends.
Show the EditCardText call
mutation EditCardText($conversationId: ID!, $assetType: String!, $assetId: String!, $text: String!) {
  updateCanvasCardText(
    input: { conversationId: $conversationId, assetType: $assetType, assetId: $assetId, text: $text }
  ) {
    success
  }
}
MupdateCanvasCardStyleRestyle a note — fill, alignment, text size. Overwritten wholesale, so send the whole style.
Show the EditNote call
mutation EditNote($conversationId: ID!, $assetId: String!, $style: CanvasCardStyleInput!) {
  updateCanvasCardStyle(
    input: { conversationId: $conversationId, assetType: "sticky_note", assetId: $assetId, style: $style }
  ) {
    success
  }
}
MupdateCanvasCardElementRewrite a shape. Send `shape` for a typed rectangle/ellipse/text; raw `element` JSON is renderer-validated on the client, so prefer the typed form.
Show the EditShape call
mutation EditShape($conversationId: ID!, $assetId: String!, $shape: CanvasCardShapeInput!) {
  updateCanvasCardElement(
    input: { conversationId: $conversationId, assetType: "element", assetId: $assetId, shape: $shape }
  ) {
    success
  }
}

Asset library

21 · browse + manage

Everything the canvas draws from — search it, and manage products, logos, fonts, tags, names, and uploads.

Search & fetch5
QassetsThe unified feed — images, videos, products, audio, logos in one paginated list.
Show the SearchAssets call
query SearchAssets(
  $workspaceId: ID!
  $first: Int = 50
  $after: String
  $term: String
  $types: [AssetType!] = [IMAGE, VIDEO, AUDIO, PROMPT, LOGO, CREATIVE]
  $contentType: AssetContentType
  $sessionIds: [ID!]
  $includeProcessing: Boolean
  $collectionId: ID
  $tags: [AssetTagFilterInput!]
) {
  assets(
    workspaceId: $workspaceId
    first: $first
    after: $after
    term: $term
    filter: {
      types: $types
      contentType: $contentType
      sessionIds: $sessionIds
      includeProcessing: $includeProcessing
      collectionId: $collectionId
      tags: $tags
    }
  ) {
    edges {
      cursor
      node {
        __typename
        ... on Image {
          id
          displayName
          status
          url
          aspectRatio
          imageType
          prompt
          width
          height
          createdAt
        }
        ... on Video {
          id
          displayName
          name
          status
          videoUrl
          thumbnailUrl
          aspectRatio
          duration
          videoType
          createdAt
        }
        ... on Logo {
          id
          logoName: name
          logoUrl: url
          fileId
          isBackgroundRemoved
          createdAt
        }
        ... on Audio {
          id
          audioName: name
          displayName
          source
          audioUrl: url
          createdAt
        }
        ... on PromptAsset {
          id
          displayName
          text
          createdAt
        }
        ... on Creative {
          id
          creativeName: name
          thumbnailUrl
          generationStatus
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
QimagesImages alone, paginated — and the poller for a generation batch.
Show the GetGenerationBatch call
query GetGenerationBatch($workspaceId: ID!, $sessionIds: [ID!]!, $first: Int = 10) {
  images(workspaceId: $workspaceId, sessionIds: $sessionIds, first: $first, includeProcessing: true) {
    edges {
      node {
        id
        status
        progress
        url
        downloadUrl
        errorMessage
        aspectRatio
        prompt
      }
    }
  }
  videos(workspaceId: $workspaceId, sessionIds: $sessionIds, first: $first, includeProcessing: true) {
    edges {
      node {
        id
        status
        progress
        videoUrl
        thumbnailUrl
        downloadUrl
        thumbnailDownloadUrl
        errorMessage
        aspectRatio
        duration
      }
    }
  }
}
QimageOne image by id, with an openable download link.
Show the GetAsset call
query GetAsset($id: ID!) {
  image(id: $id) {
    id
    displayName
    status
    progress
    url
    downloadUrl
    errorMessage
    aspectRatio
    prompt
    width
    height
  }
  video(id: $id) {
    id
    displayName
    name
    status
    progress
    videoUrl
    thumbnailUrl
    downloadUrl
    thumbnailDownloadUrl
    errorMessage
    aspectRatio
    duration
    prompt
  }
}
QvideosVideos alone, paginated.
Show the GetGenerationBatch call
query GetGenerationBatch($workspaceId: ID!, $sessionIds: [ID!]!, $first: Int = 10) {
  images(workspaceId: $workspaceId, sessionIds: $sessionIds, first: $first, includeProcessing: true) {
    edges {
      node {
        id
        status
        progress
        url
        downloadUrl
        errorMessage
        aspectRatio
        prompt
      }
    }
  }
  videos(workspaceId: $workspaceId, sessionIds: $sessionIds, first: $first, includeProcessing: true) {
    edges {
      node {
        id
        status
        progress
        videoUrl
        thumbnailUrl
        downloadUrl
        thumbnailDownloadUrl
        errorMessage
        aspectRatio
        duration
      }
    }
  }
}
QvideoOne video by id.
Show the GetAsset call
query GetAsset($id: ID!) {
  image(id: $id) {
    id
    displayName
    status
    progress
    url
    downloadUrl
    errorMessage
    aspectRatio
    prompt
    width
    height
  }
  video(id: $id) {
    id
    displayName
    name
    status
    progress
    videoUrl
    thumbnailUrl
    downloadUrl
    thumbnailDownloadUrl
    errorMessage
    aspectRatio
    duration
    prompt
  }
}
Products & brand assets4
QproductsBrowse the product catalog.
Show the ListProducts call
query ListProducts(
  $workspaceId: ID!
  $first: Int = 20
  $after: String
  $search: String
  $ids: [ID!]
  $sortBy: ProductSortField = CREATED_AT
  $sortOrder: SortOrder = DESC
) {
  products(
    workspaceId: $workspaceId
    first: $first
    after: $after
    search: $search
    ids: $ids
    sortBy: $sortBy
    sortOrder: $sortOrder
  ) {
    edges {
      cursor
      node {
        id
        name
        description
        category
        price
        currency
        websiteUrl
        createdAt
        images(first: 4) {
          edges {
            node {
              id
              url
              sortOrder
              isBackgroundRemoved
            }
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
  }
}
QproductFetch one product and its images.
Show the GetProduct call
query GetProduct($id: ID!) {
  product(id: $id) {
    id
    name
    description
    category
    price
    currency
    websiteUrl
    createdAt
    updatedAt
    images(first: 20) {
      edges {
        cursor
        node {
          id
          url
          fileId
          sortOrder
          isBackgroundRemoved
          bgRemovalStatus
          createdAt
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
    referencedImages(first: 10) {
      edges {
        node {
          id
          url
          status
          aspectRatio
          prompt
          createdAt
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}
QlogosAll brand logos.
Show the ListLogos call
query ListLogos($workspaceId: ID!, $first: Int = 50, $after: String) {
  logos(workspaceId: $workspaceId, first: $first, after: $after) {
    edges {
      cursor
      node {
        id
        name
        url
        isBackgroundRemoved
        createdAt
      }
    }
    pageInfo {
      hasNextPage
      hasPreviousPage
      startCursor
      endCursor
    }
  }
}
QfontsBrand fonts in use.
Show the ListFonts call
query ListFonts($workspaceId: ID!, $first: Int = 50, $after: String) {
  fonts(workspaceId: $workspaceId, first: $first, after: $after) {
    edges {
      cursor
      node {
        id
        name
        url
        format
        isCustom
        isDefault
        tag
        note
        createdAt
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
Tags5
QassetTagsTags on one asset.
Show the ListAssetTags call
query ListAssetTags($workspaceId: ID!, $assetId: ID!, $assetType: TaggableAssetType!) {
  assetTags(workspaceId: $workspaceId, assetId: $assetId, assetType: $assetType) {
    id
    dimension
    value
    source
    confidence
  }
}
QassetTagFacetsTag values grouped for filtering.
Show the ListAssetTagFacets call
query ListAssetTagFacets($workspaceId: ID!, $assetType: TaggableAssetType) {
  assetTagFacets(workspaceId: $workspaceId, assetType: $assetType) {
    dimension
    value
    count
  }
}
MaddAssetTagTag an asset.
Show the AddAssetTag call
mutation AddAssetTag($workspaceId: ID!, $assetId: ID!, $assetType: TaggableAssetType!, $value: String!, $dimension: String) {
  addAssetTag(
    workspaceId: $workspaceId
    assetId: $assetId
    assetType: $assetType
    value: $value
    dimension: $dimension
  ) {
    id
    dimension
    value
    source
  }
}
MremoveAssetTagUntag an asset.
Show the RemoveAssetTag call
mutation RemoveAssetTag($workspaceId: ID!, $tagId: ID!) {
  removeAssetTag(workspaceId: $workspaceId, tagId: $tagId)
}
MrequestAssetAutoTagLet AI tag an asset for you.
Show the RequestAssetAutoTag call
mutation RequestAssetAutoTag($workspaceId: ID!, $imageIds: [ID!]) {
  requestAssetAutoTag(workspaceId: $workspaceId, imageIds: $imageIds)
}
Uploads5
McreateSignedUploadUrlGet a signed URL, then PUT the bytes straight to storage.
Show the CreateSignedUploadUrl call
mutation CreateSignedUploadUrl(
  $category: UploadCategory!
  $filename: String!
  $contentType: String!
  $workspaceId: ID
  $entityId: ID
) {
  createSignedUploadUrl(
    category: $category
    filename: $filename
    contentType: $contentType
    workspaceId: $workspaceId
    entityId: $entityId
  ) {
    fileId
    signedUrl
    bucket
    storagePath
    publicUrl
    provider
  }
}
MuploadImageRegister an uploaded image into the library.
Show the UploadImage call
mutation UploadImage($workspaceId: ID!, $fileId: ID!, $id: ID, $name: String, $aspectRatio: String) {
  uploadImage(workspaceId: $workspaceId, input: { id: $id, fileId: $fileId, name: $name, aspectRatio: $aspectRatio }) {
    success
    image {
      id
      url
      fileId
      imageType
      status
      aspectRatio
      width
      height
      createdAt
    }
  }
}
MuploadVideoRegister an uploaded video into the library.
Show the UploadVideo call
mutation UploadVideo(
  $workspaceId: ID!
  $fileId: ID!
  $id: ID
  $name: String
  $displayName: String
  $duration: Float
  $aspectRatio: String
  $thumbnailFileId: ID
) {
  uploadVideo(
    workspaceId: $workspaceId
    input: {
      id: $id
      fileId: $fileId
      name: $name
      displayName: $displayName
      duration: $duration
      aspectRatio: $aspectRatio
      thumbnailFileId: $thumbnailFileId
    }
  ) {
    success
    video {
      id
      status
      videoUrl
      thumbnailUrl
      duration
      aspectRatio
      createdAt
    }
  }
}
MuploadAudioRegister an uploaded audio file into the library.
Show the UploadAudio call
mutation UploadAudio(
  $workspaceId: ID!
  $fileId: ID!
  $id: ID
  $name: String
  $displayName: String
  $durationMs: Int
  $contentType: String
) {
  uploadAudio(
    workspaceId: $workspaceId
    input: {
      id: $id
      fileId: $fileId
      name: $name
      displayName: $displayName
      durationMs: $durationMs
      contentType: $contentType
    }
  ) {
    success
    audio {
      id
      source
      url
      downloadUrl
      durationMs
      createdAt
    }
  }
}
MconfirmFileUploadFinalize an upload with no register step, so cleanup will not delete it.
Show the ConfirmFileUpload call
mutation ConfirmFileUpload($fileId: ID!) {
  confirmFileUpload(fileId: $fileId)
}
Naming2
MupdateImageRename an image — the name every surface then shows.
Show the EditImage call
mutation EditImage($id: ID!, $upscaleScale: String, $removeBackground: Boolean, $fileId: String) {
  updateImage(id: $id, input: { upscaleScale: $upscaleScale, removeBackground: $removeBackground, fileId: $fileId }) {
    success
    image {
      id
      status
      url
      aspectRatio
      width
      height
      isBackgroundRemoved
      isUpscaled
    }
  }
}
MupdateVideoRename a video.
Show the EditVideo call
mutation EditVideo($id: ID!, $upscaleScale: String, $removeBackground: Boolean) {
  updateVideo(id: $id, input: { upscaleScale: $upscaleScale, removeBackground: $removeBackground }) {
    success
    video {
      id
      status
      videoUrl
      thumbnailUrl
      duration
      aspectRatio
      model
    }
  }
}

Generation & editing

14 · create

The same options the canvas composer offers — plus the pollers that collect async results.

Discover first2
QavailableGenerationModelsModels per role with their limits and defaults — the source for valid model, quality, and resolution values.
Show the ListGenerationModels call
query ListGenerationModels {
  availableGenerationModels {
    imageModels {
      id
      label
      provider
      description
      promptGuidance
      recommendedFor
      supportedDurations
      defaultDuration
      supportedResolutions
      defaultResolution
      supportedQualities
      defaultQuality
      maxReferenceImages
      supportsVideoToVideo
      estimatedCredits
    }
    videoModels {
      id
      label
      provider
      description
      promptGuidance
      recommendedFor
      supportedDurations
      defaultDuration
      supportedResolutions
      defaultResolution
      supportedQualities
      defaultQuality
      maxReferenceImages
      maxReferenceVideos
      maxReferenceAudios
      maxReferenceFiles
      supportsVideoToVideo
      estimatedCredits
    }
    referenceToVideoModels {
      id
      label
      provider
      description
      promptGuidance
      recommendedFor
      supportedDurations
      defaultDuration
      supportedResolutions
      defaultResolution
      supportedQualities
      defaultQuality
      maxReferenceImages
      maxReferenceVideos
      maxReferenceAudios
      maxReferenceFiles
      supportsVideoToVideo
      estimatedCredits
    }
    speakingAvatarModels {
      id
      label
      provider
      description
      promptGuidance
      recommendedFor
      supportedResolutions
      defaultResolution
      maxReferenceImages
      estimatedCredits
    }
    lipSyncModels {
      id
      label
      provider
      description
      promptGuidance
      recommendedFor
      estimatedCredits
    }
    musicModels {
      id
      label
      provider
      description
      promptGuidance
      recommendedFor
      supportedDurations
      defaultDuration
      estimatedCredits
    }
    voiceModels {
      id
      label
      provider
      description
      promptGuidance
      recommendedFor
      estimatedCredits
    }
    defaultImageModelId
    defaultVideoModelId
    defaultReferenceToVideoModelId
    defaultSpeakingAvatarModelId
    defaultLipSyncModelId
    defaultMusicModelId
    defaultVoiceModelId
  }
}
QstudioPresetsPageThe modifier catalog — pass the slugs you pick as `presetSlugs` to style a generation the way the canvas composer does.
Show the ListModifiers call
query ListModifiers($term: String, $category: String, $limit: Int = 40, $offset: Int = 0) {
  studioPresetsPage(q: $term, category: $category, limit: $limit, offset: $offset, surface: "composer") {
    totalCount
    items {
      slug
      title
      description
      category
      outputFormat
      stackable
      defaultAspectRatio
      thumbnailUrl
      posterUrl
    }
  }
}
Image1
MgenerateImageGenerate or edit images — prompt, aspect ratio, count, quality, and reference images.
Show the GenerateImage call
mutation GenerateImage(
  $workspaceId: ID!
  $prompt: String!
  $aspectRatio: String!
  $count: Int = 1
  $model: String
  $quality: String
  $resolution: String
  $referenceImages: [ReferenceImageInput!]
  $parentImageId: ID
  $sessionId: ID
  $presetSlugs: [String!]
) {
  generateImage(
    workspaceId: $workspaceId
    input: {
      prompt: $prompt
      aspectRatio: $aspectRatio
      count: $count
      model: $model
      quality: $quality
      resolution: $resolution
      referenceImages: $referenceImages
      parentImageId: $parentImageId
      sessionId: $sessionId
      presetSlugs: $presetSlugs
    }
  ) {
    success
    images {
      id
      status
      url
      sessionId
      aspectRatio
      model
      prompt
    }
  }
}
Video6
MgenerateVideoGenerate video — optionally with audio, reference images, or a source video.
Show the GenerateVideo call
mutation GenerateVideo(
  $workspaceId: ID!
  $prompt: String!
  $aspectRatio: String!
  $model: String
  $duration: Float
  $resolution: String
  $addMusic: Boolean
  $generateAudio: Boolean
  $firstFrame: ReferenceImageInput
  $endImage: ReferenceImageInput
  $referenceImages: [ReferenceImageInput!]
  $referenceVideos: [ReferenceImageInput!]
  $referenceAudios: [ReferenceImageInput!]
  $sourceVideo: ReferenceImageInput
  $presetSlugs: [String!]
  $sessionId: ID
) {
  generateVideo(
    workspaceId: $workspaceId
    input: {
      prompt: $prompt
      aspectRatio: $aspectRatio
      model: $model
      duration: $duration
      resolution: $resolution
      addMusic: $addMusic
      generateAudio: $generateAudio
      firstFrame: $firstFrame
      endImage: $endImage
      referenceImages: $referenceImages
      referenceVideos: $referenceVideos
      referenceAudios: $referenceAudios
      sourceVideo: $sourceVideo
      presetSlugs: $presetSlugs
      sessionId: $sessionId
    }
  ) {
    success
    video {
      id
      status
      sessionId
      videoUrl
      thumbnailUrl
      duration
      aspectRatio
      model
    }
  }
}
MgenerateVideoFormatVariantReframe or crop to another aspect ratio.
Show the GenerateVideoFormatVariant call
mutation GenerateVideoFormatVariant($videoId: ID!, $targetAspectRatio: String!, $mode: VideoFormatVariantMode!) {
  generateVideoFormatVariant(input: { videoId: $videoId, targetAspectRatio: $targetAspectRatio, mode: $mode }) {
    success
    video {
      id
      status
      videoUrl
      thumbnailUrl
      duration
      aspectRatio
      model
    }
  }
}
MapplyVideoColorAdjustmentsGrade and color-correct a video.
Show the AdjustVideoColor call
mutation AdjustVideoColor(
  $id: ID!
  $exposure: Int!
  $contrast: Int!
  $saturation: Int!
  $temperature: Int!
  $tint: Int!
  $highlights: Int!
  $shadows: Int!
) {
  applyVideoColorAdjustments(
    id: $id
    input: {
      exposure: $exposure
      contrast: $contrast
      saturation: $saturation
      temperature: $temperature
      tint: $tint
      highlights: $highlights
      shadows: $shadows
    }
  ) {
    success
    video {
      id
      status
      videoUrl
      thumbnailUrl
      duration
      aspectRatio
      model
    }
  }
}
MaddSubtitlesTranscribe and burn subtitles into a video.
Show the AddSubtitles call
mutation AddSubtitles(
  $workspaceId: ID!
  $videoId: ID
  $videoUrl: String
  $language: String
  $fontName: String
  $fontSize: Int
  $fontWeight: String
  $fontColor: String
  $highlightColor: String
  $strokeWidth: Int
  $strokeColor: String
  $backgroundColor: String
  $backgroundOpacity: Float
  $position: String
  $yOffset: Int
  $wordsPerSubtitle: Int
  $enableAnimation: String
) {
  addSubtitles(
    workspaceId: $workspaceId
    input: {
      videoId: $videoId
      videoUrl: $videoUrl
      language: $language
      fontName: $fontName
      fontSize: $fontSize
      fontWeight: $fontWeight
      fontColor: $fontColor
      highlightColor: $highlightColor
      strokeWidth: $strokeWidth
      strokeColor: $strokeColor
      backgroundColor: $backgroundColor
      backgroundOpacity: $backgroundOpacity
      position: $position
      yOffset: $yOffset
      wordsPerSubtitle: $wordsPerSubtitle
      enableAnimation: $enableAnimation
    }
  ) {
    success
    video {
      id
      status
      videoUrl
      thumbnailUrl
      duration
      aspectRatio
      model
    }
  }
}
MgenerateLipsyncSync a video's mouth to an audio track.
Show the GenerateLipsync call
mutation GenerateLipsync(
  $workspaceId: ID!
  $videoId: ID
  $videoUrl: String
  $audioId: ID
  $audioUrl: String
  $audioDurationSeconds: Float
  $model: String
  $emotion: LipsyncEmotion
  $syncMode: LipsyncSyncMode
  $faceMode: LipsyncFaceMode
  $enableCaption: Boolean
) {
  generateLipsync(
    workspaceId: $workspaceId
    input: {
      videoId: $videoId
      videoUrl: $videoUrl
      audioId: $audioId
      audioUrl: $audioUrl
      audioDurationSeconds: $audioDurationSeconds
      model: $model
      emotion: $emotion
      syncMode: $syncMode
      faceMode: $faceMode
      enableCaption: $enableCaption
    }
  ) {
    success
    video {
      id
      status
      videoUrl
      thumbnailUrl
      duration
      aspectRatio
      model
    }
  }
}
MgenerateSpeakingCharacterGenerate a speaking character or avatar.
Show the GenerateSpeakingCharacter call
mutation GenerateSpeakingCharacter(
  $workspaceId: ID!
  $imageId: ID
  $imageUrl: String
  $audioId: ID
  $audioUrl: String
  $audioDurationSeconds: Float
  $model: String
  $resolution: String
) {
  generateSpeakingCharacter(
    workspaceId: $workspaceId
    input: {
      imageId: $imageId
      imageUrl: $imageUrl
      audioId: $audioId
      audioUrl: $audioUrl
      audioDurationSeconds: $audioDurationSeconds
      model: $model
      resolution: $resolution
    }
  ) {
    success
    video {
      id
      status
      videoUrl
      thumbnailUrl
      duration
      aspectRatio
      model
    }
  }
}
Audio3
MgenerateMusicTrackCompose a music track.
Show the GenerateMusic call
mutation GenerateMusic(
  $workspaceId: ID!
  $provider: String!
  $prompt: String!
  $tags: [String!]
  $lyrics: String
  $instrumental: Boolean
  $minDurationSeconds: Int
  $maxDurationSeconds: Int
) {
  generateMusicTrack(
    workspaceId: $workspaceId
    input: {
      provider: $provider
      prompt: $prompt
      tags: $tags
      lyrics: $lyrics
      instrumental: $instrumental
      minDurationSeconds: $minDurationSeconds
      maxDurationSeconds: $maxDurationSeconds
    }
  ) {
    success
    audioId
    jobId
    estimatedCredits
  }
}
MgenerateVoiceoverGenerate a voiceover.
Show the GenerateVoiceover call
mutation GenerateVoiceover(
  $workspaceId: ID!
  $script: String!
  $voiceId: String
  $emotion: String
  $language: String
  $speed: Float
  $stability: Float
  $similarityBoost: Float
  $style: Float
  $useSpeakerBoost: Boolean
  $name: String
) {
  generateVoiceover(
    workspaceId: $workspaceId
    input: {
      script: $script
      voiceId: $voiceId
      emotion: $emotion
      language: $language
      speed: $speed
      stability: $stability
      similarityBoost: $similarityBoost
      style: $style
      useSpeakerBoost: $useSpeakerBoost
      name: $name
    }
  ) {
    success
    audioId
    jobId
  }
}
MgenerateVideoSfxGenerate sound effects for a video.
Show the GenerateVideoSfx call
mutation GenerateVideoSfx(
  $workspaceId: ID!
  $videoId: ID
  $videoUrl: String
  $prompt: String
  $videoDurationSeconds: Float
  $aspectRatio: String
) {
  generateVideoSfx(
    workspaceId: $workspaceId
    input: {
      videoId: $videoId
      videoUrl: $videoUrl
      prompt: $prompt
      videoDurationSeconds: $videoDurationSeconds
      aspectRatio: $aspectRatio
    }
  ) {
    success
    audioId
    jobId
  }
}
Jobs & status2
QbackgroundJobTrack brand-analysis and product-scrape jobs.
Show the GetBackgroundJob call
query GetBackgroundJob($id: ID!, $workspaceId: ID!) {
  backgroundJob(id: $id, workspaceId: $workspaceId) {
    id
    type
    status
    source
    sourceId
    metadata
    createdAt
    completedAt
    children {
      id
      type
      status
      createdAt
      completedAt
    }
  }
}
QaudioStatusTrack music, voiceover, and SFX jobs to the finished audio.
Show the GetAudioStatus call
query GetAudioStatus($audioId: ID!, $workspaceId: ID!) {
  audioStatus(audioId: $audioId, workspaceId: $workspaceId) {
    audioId
    status
    progress
    errorMessage
    audio {
      id
      source
      url
      downloadUrl
      durationMs
      name
      model
      musicProvider
      createdAt
    }
  }
}