Image Layer Operations Migration

This guide helps you migrate image layer and solid color layer operations from v1's /documentCreate and /documentOperations endpoints to v2's /create-composite endpoint.

Overview

The v1 endpoints /pie/psdService/documentCreate and /pie/psdService/documentOperations were used to create documents with image/fill layers and add/edit image/fill layers respectively.

Now in the v2 API, all layer operations are unified into the /v2/create-composite endpoint with the edits.layers array.

Layer types covered in this guide are:

Key migration changes

1. Add operation structure

In the v1 API, the add block was used with insert instructions to specify the placement of the new layer.

{
  "type": "layer",
  "name": "New Layer",
  "add": {
    "insertTop": true
  },
  "input": {
    "href": "<URL>",
    "storage": "external"
  }
}

In the v2 API, one operation block is used with the placement property to specify the placement of the new layer.

{
  "type": "layer",
  "name": "New Layer",
  "image": {
    "source": {
      "url": "<URL>"
    }
  },
  "operation": {
    "type": "add",
    "placement": {
      "type": "top"
    }
  }
}

2. Image source property

The v1 API used the input object.

{
  "input": {
    "href": "<URL>",
    "storage": "external"
  }
}

The v2 API uses the image.source object.

{
  "image": {
    "source": {
      "url": "<URL>"
    }
  }
}

3. Layer placement

Layer placement is now specified in the operation.placement property. See the Layer placement migration patterns section for more details.

Adding image layers

V1 approach

The v1 API used the /documentOperations endpoint with the add block to add a new image layer.

curl -X POST \
  https://image.adobe.io/pie/psdService/documentOperations \
  -H "Authorization: Bearer $token" \
  -H "x-api-key: $apiKey" \
  -H "Content-Type: application/json" \
  -d '{
  "inputs": [{
    "href": "<SIGNED_GET_URL>",
    "storage": "external"
  }],
  "options": {
    "layers": [
      {
        "type": "layer",
        "name": "New Image",
        "add": {
          "insertTop": true
        },
        "input": {
          "href": "<IMAGE_URL>",
          "storage": "external"
        }
      }
    ]
  },
  "outputs": [{
    "href": "<SIGNED_POST_URL>",
    "storage": "external",
    "type": "image/vnd.adobe.photoshop"
  }]
}'

V2 approach

curl -X POST \
  https://photoshop-api.adobe.io/v2/create-composite \
  -H "Authorization: Bearer $token" \
  -H "x-api-key: $apiKey" \
  -H "Content-Type: application/json" \
  -d '{
  "image": {
    "source": {
      "url": "<SIGNED_GET_URL>"
    }
  },
  "edits": {
    "layers": [
      {
        "type": "layer",
        "name": "New Image",
        "image": {
          "source": {
            "url": "<IMAGE_URL>"
          }
        },
        "operation": {
          "type": "add",
          "placement": {
            "type": "top"
          }
        }
      }
    ]
  },
  "outputs": [
    {
      "destination": {
        "url": "<SIGNED_POST_URL>"
      },
      "mediaType": "image/vnd.adobe.photoshop"
    }
  ]
}'

Layer placement migration patterns

In the v1 API, the placement options were controlled by these parameters:

In the v2 API, the corresponding placement options are controlled by the operation.placement property:

Insert at Top

V1:

{
  "add": {
    "insertTop": true
  }
}

V2:

{
  "operation": {
    "type": "add",
    "placement": {
      "type": "top"
    }
  }
}

Insert at Bottom

V1:

{
  "add": {
    "insertBottom": true
  }
}

V2:

{
  "operation": {
    "type": "add",
    "placement": {
      "type": "bottom"
    }
  }
}

Insert Above Layer

V1:

{
  "add": {
    "insertAbove": {
      "name": "Background"
    }
  }
}

V2:

{
  "operation": {
    "type": "add",
    "placement": {
      "type": "above",
      "relativeTo": {
        "name": "Background"
      }
    }
  }
}

Insert Below Layer

V1:

{
  "add": {
    "insertBelow": {
      "id": 123
    }
  }
}

V2:

{
  "operation": {
    "type": "add",
    "placement": {
      "type": "below",
      "relativeTo": {
        "id": 123
      }
    }
  }
}

Insert Into Group

V1:

{
  "add": {
    "insertInto": {
      "name": "My Group"
    }
  }
}

V2:

{
  "operation": {
    "type": "add",
    "placement": {
      "type": "inside",
      "relativeTo": {
        "name": "My Group"
      }
    }
  }
}

Solid Color Layers

V1 approach: fillLayer

curl -X POST \
  https://image.adobe.io/pie/psdService/documentOperations \
  -H "Authorization: Bearer $token" \
  -H "x-api-key: $apiKey" \
  -H "Content-Type: application/json" \
  -d '{
  "inputs": [{
    "href": "<SIGNED_GET_URL>",
    "storage": "external"
  }],
  "options": {
    "layers": [
      {
        "type": "fillLayer",
        "name": "Red Fill",
        "add": {
          "insertTop": true
        },
        "fill": {
          "solidColor": {
            "rgb": {
              "red": 255,
              "green": 0,
              "blue": 0
            }
          }
        }
      }
    ]
  },
  "outputs": [{
    "href": "<SIGNED_POST_URL>",
    "storage": "external",
    "type": "image/vnd.adobe.photoshop"
  }]
}'

V2 approach

curl -X POST \
  https://photoshop-api.adobe.io/v2/create-composite \
  -H "Authorization: Bearer $token" \
  -H "x-api-key: $apiKey" \
  -H "Content-Type: application/json" \
  -d '{
  "image": {
    "source": {
      "url": "<SIGNED_GET_URL>"
    }
  },
  "edits": {
    "layers": [
      {
        "type": "solid_color_layer",
        "name": "Red Fill",
        "fill": {
          "solidColor": {
            "rgb": {
              "red": 255,
              "green": 0,
              "blue": 0
            }
          }
        },
        "operation": {
          "type": "add",
          "placement": {
            "type": "top"
          }
        }
      }
    ]
  },
  "outputs": [
    {
      "destination": {
        "url": "<SIGNED_POST_URL>"
      },
      "mediaType": "image/vnd.adobe.photoshop"
    }
  ]
}'

Solid Color Layer Changes

V1: type: "fillLayer" with nested rgb object

{
  "type": "fillLayer",
  "fill": {
    "solidColor": {
      "rgb": {
        "red": 255,
        "green": 0,
        "blue": 0
      }
    }
  }
}

V2: type: "solid_color_layer" with direct color properties

{
  "type": "solid_color_layer",
  "fill": {
    "solidColor": {
      "rgb": {
        "red": 255,
        "green": 0,
        "blue": 0
      }
    }
  }
}

Editing Existing Layers

V1 approach: edit block

{
  "options": {
    "layers": [
      {
        "name": "Existing Layer",
        "edit": {},
        "visible": false,
        "blendOptions": {
          "opacity": 75
        }
      }
    ]
  }
}

V2 approach

{
  "edits": {
    "layers": [
      {
        "name": "Existing Layer",
        "isVisible": false,
        "opacity": 75
      }
    ]
  }
}
data-variant=info
data-slots=text
In V2, editing existing layers doesn't require an explicit operation type. Simply reference the layer by name or ID and specify the properties to change.

Replacing Layer Content

V1 approach

{
  "options": {
    "layers": [
      {
        "name": "Existing Layer",
        "edit": {},
        "input": {
          "href": "<NEW_IMAGE_URL>",
          "storage": "external"
        }
      }
    ]
  }
}

V2 approach

{
  "edits": {
    "layers": [
      {
        "name": "Existing Layer",
        "image": {
          "source": {
            "url": "<NEW_IMAGE_URL>"
          }
        }
      }
    ]
  }
}

Layer Positioning

Using Bounds

Both V1 and V2 support explicit positioning:

V1:

{
  "type": "layer",
  "name": "Positioned Image",
  "bounds": {
    "left": 100,
    "top": 100,
    "width": 500,
    "height": 300
  }
}

V2: (Same pattern)

{
  "type": "layer",
  "name": "Positioned Image",
  "bounds": {
    "left": 100,
    "top": 100,
    "width": 500,
    "height": 300
  }
}

Alignment Options

V1: horizontalAlign and verticalAlign

{
  "type": "layer",
  "horizontalAlign": "center",
  "verticalAlign": "center"
}

V2: Uses placement alignment

{
  "type": "layer",
  "operation": {
    "type": "add",
    "placement": {
      "type": "custom",
      "horizontalAlignment": "center",
      "verticalAlignment": "center"
    }
  }
}

Fill to Canvas

V1: fillToCanvas property

{
  "type": "layer",
  "fillToCanvas": true
}

V2: Not yet available

data-variant=warning
data-slots=text
The fillToCanvas property from V1 is not yet available in V2. Contact Adobe DI ART Service team if you need this feature.

Creating Documents with Image Layers

V1 approach: documentCreate

{
  "options": {
    "document": {
      "width": 1000,
      "height": 1000,
      "resolution": 72,
      "fill": "white",
      "mode": "rgb"
    },
    "layers": [
      {
        "type": "layer",
        "name": "Logo",
        "input": {
          "href": "<IMAGE_URL>",
          "storage": "external"
        }
      }
    ]
  }
}

V2 approach

{
  "document": {
    "width": 1000,
    "height": 1000,
    "resolution": 72,
    "fill": {
      "solidColor": {
        "red": 255,
        "green": 255,
        "blue": 255
      }
    },
    "mode": "rgb"
  },
  "edits": {
    "layers": [
      {
        "type": "layer",
        "name": "Logo",
        "image": {
          "source": {
            "url": "<IMAGE_URL>"
          }
        },
        "operation": {
          "type": "add"
        }
      }
    ]
  }
}

Migration checklist

When migrating image layer operations from v1 to v2:

Common migration issues

Missing placement for an add operation

The v2 API requires explicit placement for an add operation. Always specify placement type.

{
  "operation": {
    "type": "add",
    "placement": {
      "type": "top"
    }
  }
}

Storage type changes

V1: Required explicit storage type

{
  "href": "<URL>",
  "storage": "external"
}

V2: Storage type optional, defaults to external

{
  "url": "<URL>"
}

Solid color structure

V1: Nested rgb object

{
  "fill": {
    "solidColor": {
      "rgb": {
        "red": 255,
        "green": 0,
        "blue": 0
      }
    }
  }
}

V2: Same nested structure

{
  "fill": {
    "solidColor": {
      "rgb": {
        "red": 255,
        "green": 0,
        "blue": 0
      }
    }
  }
}

Complete Migration Example

V1 documentOperations:

{
  "inputs": [
    {
      "href": "<SIGNED_GET_URL>",
      "storage": "external"
    }
  ],
  "options": {
    "layers": [
      {
        "type": "layer",
        "name": "Hero Image",
        "add": {
          "insertTop": true
        },
        "input": {
          "href": "<IMAGE_URL>",
          "storage": "external"
        },
        "bounds": {
          "left": 0,
          "top": 0,
          "width": 1920,
          "height": 600
        }
      },
      {
        "type": "fillLayer",
        "name": "Background",
        "add": {
          "insertBottom": true
        },
        "fill": {
          "solidColor": {
            "rgb": {
              "red": 240,
              "green": 240,
              "blue": 240
            }
          }
        }
      }
    ]
  },
  "outputs": [
    {
      "href": "<SIGNED_POST_URL>",
      "storage": "external",
      "type": "image/vnd.adobe.photoshop"
    }
  ]
}

V2 create-composite:

{
  "image": {
    "source": {
      "url": "<SIGNED_GET_URL>"
    }
  },
  "edits": {
    "layers": [
      {
        "type": "layer",
        "name": "Hero Image",
        "image": {
          "source": {
            "url": "<IMAGE_URL>"
          }
        },
        "bounds": {
          "left": 0,
          "top": 0,
          "width": 1920,
          "height": 600
        },
        "operation": {
          "type": "add",
          "placement": {
            "type": "top"
          }
        }
      },
      {
        "type": "solid_color_layer",
        "name": "Background",
        "fill": {
          "solidColor": {
            "rgb": {
              "red": 240,
              "green": 240,
              "blue": 240
            }
          }
        },
        "operation": {
          "type": "add",
          "placement": {
            "type": "bottom"
          }
        }
      }
    ]
  },
  "outputs": [
    {
      "destination": {
        "url": "<SIGNED_POST_URL>"
      },
      "mediaType": "image/vnd.adobe.photoshop"
    }
  ]
}

Feature Availability

Currently Available in V2

V1 Features Not Yet in V2

data-variant=info
data-slots=text
If you rely on v1 features not yet in v2, contact the Adobe DI ART Service team to discuss alternatives or timeline.

Need Help?

Contact the Adobe DI ART Service team for technical support with image layer migration.