Adobe Photoshop · Arazzo Workflow

Adobe Photoshop Generative Fill from a Generated Mask

Version 1.0.0

Generate a subject mask with background removal, then fill the masked area with generative AI.

1 workflow 1 source API 1 provider
View Spec View on GitHub AI/MLCreative CloudImage EditingPhotoshopPluginsREST APIScriptingArazzoWorkflows

Provider

adobe-photoshop

Workflows

generative-fill
Derive a mask via background removal and fill that region with generative AI.
Submits the image for mask-mode background removal, polls the Sensei job for the mask, then submits the image and mask to the generative fill endpoint and polls that job to completion.
4 steps inputs: imageUrl outputs: filledHref, maskHref, status
1
submitMask
removeBackgroundV2
Run background removal in mask mode, which returns a grayscale mask of the detected subject rather than a cutout. That mask defines the region the generative fill step will replace.
2
awaitMask
getSenseiJobStatus
Poll the Sensei status endpoint until the mask is ready. The submit call returns the absolute status URL in _links.self.href; the jobId this operation requires is the final path segment of that URL, so a runner takes that segment from statusHref before issuing the request.
3
submitFill
fillMaskedAreas
Submit the original image together with the generated mask so the generative service synthesizes new content into the masked region.
4
awaitFill
getSenseiJobStatus
Poll the Sensei status endpoint until the generative fill job reports succeeded and the filled image is available.

Source API Descriptions

Arazzo Workflow Specification

Raw ↑
arazzo: 1.0.1
info:
  title: Adobe Photoshop Generative Fill from a Generated Mask
  summary: Generate a subject mask with background removal, then fill the masked area with generative AI.
  description: >-
    Generative fill needs a mask, and the background removal endpoint can produce
    one. This workflow runs removal in mask mode to derive a grayscale mask of the
    subject, waits for it, and then hands the source image plus that mask to the
    generative fill endpoint, which synthesizes new content into the masked
    region. This removes the usual prerequisite of authoring a mask by hand before
    calling the generative endpoint. Every step spells out its request inline so
    the flow can be read and executed without opening the underlying OpenAPI.
  version: 1.0.0
sourceDescriptions:
- name: photoshopApi
  url: ../openapi/adobe-photoshop-api-openapi-original.yml
  type: openapi
workflows:
- workflowId: generative-fill
  summary: Derive a mask via background removal and fill that region with generative AI.
  description: >-
    Submits the image for mask-mode background removal, polls the Sensei job for
    the mask, then submits the image and mask to the generative fill endpoint and
    polls that job to completion.
  inputs:
    type: object
    required:
    - imageUrl
    properties:
      imageUrl:
        type: string
        description: Pre-signed GET URL of the source image to fill.
  steps:
  - stepId: submitMask
    description: >-
      Run background removal in mask mode, which returns a grayscale mask of the
      detected subject rather than a cutout. That mask defines the region the
      generative fill step will replace.
    operationId: removeBackgroundV2
    requestBody:
      contentType: application/json
      payload:
        image:
          source:
            url: $inputs.imageUrl
        mode: mask
        output:
          mediaType: image/png
    successCriteria:
    - condition: $statusCode == 202
    outputs:
      statusHref: $response.body#/_links/self/href
  - stepId: awaitMask
    description: >-
      Poll the Sensei status endpoint until the mask is ready. The submit call
      returns the absolute status URL in _links.self.href; the jobId this
      operation requires is the final path segment of that URL, so a runner takes
      that segment from statusHref before issuing the request.
    operationId: getSenseiJobStatus
    parameters:
    - name: jobId
      in: path
      value: $steps.submitMask.outputs.statusHref
    successCriteria:
    - condition: $statusCode == 200
    - context: $response.body
      condition: $.outputs[0].status == 'succeeded'
      type: jsonpath
    onFailure:
    - name: keepPolling
      type: retry
      retryAfter: 3
      retryLimit: 20
      criteria:
      - context: $response.body
        condition: $.outputs[0].status == 'pending' || $.outputs[0].status == 'running'
        type: jsonpath
    - name: maskFailed
      type: end
      criteria:
      - context: $response.body
        condition: $.outputs[0].status == 'failed'
        type: jsonpath
    outputs:
      maskHref: $response.body#/outputs/0/_links/self/href
  - stepId: submitFill
    description: >-
      Submit the original image together with the generated mask so the
      generative service synthesizes new content into the masked region.
    operationId: fillMaskedAreas
    requestBody:
      contentType: application/json
      payload:
        image:
          source:
            url: $inputs.imageUrl
        masks:
        - source:
            url: $steps.awaitMask.outputs.maskHref
    successCriteria:
    - condition: $statusCode == 202
    outputs:
      statusHref: $response.body#/_links/self/href
  - stepId: awaitFill
    description: >-
      Poll the Sensei status endpoint until the generative fill job reports
      succeeded and the filled image is available.
    operationId: getSenseiJobStatus
    parameters:
    - name: jobId
      in: path
      value: $steps.submitFill.outputs.statusHref
    successCriteria:
    - condition: $statusCode == 200
    - context: $response.body
      condition: $.outputs[0].status == 'succeeded'
      type: jsonpath
    onFailure:
    - name: keepPolling
      type: retry
      retryAfter: 3
      retryLimit: 20
      criteria:
      - context: $response.body
        condition: $.outputs[0].status == 'pending' || $.outputs[0].status == 'running'
        type: jsonpath
    - name: fillFailed
      type: end
      criteria:
      - context: $response.body
        condition: $.outputs[0].status == 'failed'
        type: jsonpath
    outputs:
      status: $response.body#/outputs/0/status
      filledHref: $response.body#/outputs/0/_links/self/href
  outputs:
    maskHref: $steps.awaitMask.outputs.maskHref
    filledHref: $steps.awaitFill.outputs.filledHref
    status: $steps.awaitFill.outputs.status