Table of Contents generated with DocToc
- Private Beta
- Welcome to Photoshop APIs!
- General Setup and Onboarding
- Photoshop
- General Workflow
- Supported Features
- How to use the APIs
- Sample Code
- Current Limitations
- ImageCutout
- Lightroom APIs
The Photoshop APIs are made available through an invitation only Private Beta. In order to be considered for the Private Beta please apply here https://photoshop.adobelanding.com/api-signup/
Make sure to take a look at the Pre-release agreement before applying and ensure you understand the aspects of the program.
The Adobe Photoshop API gives you access to a subset of Photoshop, Lightroom, and Sensei services. The API will allow you to make both layer and document level edits to Photoshop PSD files as well as perform a number of image edits and improvements.
The Photoshop API is designed with REST like principles and uses standard HTTP response codes, verbs and authentication and returns JSON-encoded responses.
The links below provide more detailed information about the API services including code samples and reference guides. Once you are done setting up your Authentication you can dive into these links.
The API documentation is published at
The Photoshop API uses client id’s (also know as api keys) and authentication tokens to authenticate requests. There are two different kinds of authorization tokens available:
- Individual user access (OAuth 2.0 access token)
- Adobe Enterprise ETLA (Service token using JSON Web Token/JWT)
If this is your first time using Adobe API’s we suggest trying out the OAuth workflow.
In order to use the Photoshop API's you’ll need to get a Client ID (also known as an API key) and a Client Secret. Once you have those you can use them to programmatically get an access token to authenticate your requests. We’ll walk you through the steps below.
Here are the workflows we currently support. You are…
- An individual user logged in who has an Adobe Creative Cloud Account
- An organization with an Adobe ETLA (an enterprise account)
- Running a job on a server
- Running in a browser
If your workflow falls outside of these please contact us at [email protected] so we can help meet your needs.
-
Get your client id and client secret. After you've been accepted to the PreRelease program you will be emailed your credentials (your client ID and client Secret) required for API authentication.
-
Test out your credentials. This will allow you to verify that your credentials work and show you want an OAuth token looks like for when you eventually do this programmatically.
- Browse to https://ps-prerelease-us-east-1.cloud.adobe.io
- Enter the client id and secret
- Follow through the login process
- If your credentials work you should see an authorization token appear on your screen This is the OAuth token that’s required to make calls to the Photoshop API’s and if you’d like you can jump ahead and immediately try them out now. Eventually you will make this process programmatic (instructions below) but in the meantime the token expires in 24 hours and you can use this workflow during development for as long as you’d like.
- Make an authenticated call to ensure you can round trip successfully with the API’s
curl --request GET \
--url https://image.adobe.io/pie/psdService/hello \
--header 'Authorization: Bearer <YOUR_OAUTH_TOKEN>' \
--header 'x-api-key: <YOUR_CLIENT_ID>' \
Congrats! You just made your first request to the Photoshop API.
- Make a Photoshop API call with real assets
Now that you can successfully authenticate and talk to the API’s it’s time to make “real” calls…
curl -X POST \
https://image.adobe.io/pie/psdService/documentManifest \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>' \
-d '{
"inputs": [
{
"href":"files/Example.psd",
"storage":"adobe"
}
]
}'
- Notes on token retrieval
The access token must never be transmitted as a URI parameter. Doing so would expose it to being captured in-the-clear by intermediaries such as proxy server logs. The API does not allow you to send an access token anywhere except the Authorization header field.
Your access token will expire typically in 24 hours. You will receive a ‘refresh_token’ when you initially obtain the access token that you can use to get a new access token. Be aware that refreshing your token might require a new login event. Please reference the OAuth documentation for additional instructions.
- Automate token retrieval
Please contact [email protected] for more information on how you can automate token generation for your workflow.
You can find details on interacting with Adobe IMS API’s and authentication in general
In order to be an enterprise user you must already have an ETLA. To find out if you have an ETLA reach out to your system administrator or your Adobe Account Executive.
Enterprise users will not have access to assets stored in the Creative Cloud so you must use an external storage source when making calls to the API.
- Get a developer role in the Adobe Admin Console You system admin will need to give you developer access in the Adobe Admin Console
- Go to https://console.adobe.io and create a service integration and follow the instructions at Service Token Instructions
On Step 1 of the Service Integration docs, ‘Subscribe to an Adobe Service’ you will select the following 1. Photoshop 2. Lightroom / Camera Raw API 3. Image Cutout
- Create a JSON Web Token (JWT) and exchange it for an access token Take the information from your integration, plus your private key that you created when you created your integration and follow the instructions at JWT Instructions:
You can refer to JWT sample code for additional help
- Make your first Photoshop API call Make an authenticated call to ensure you can round trip successfully with the API’s
curl --request GET \
--url https://image.adobe.io/pie/psdService/hello \
--header 'Authorization: Bearer <YOUR_SERVICE_TOKEN>' \
--header 'x-api-key: <YOUR_CLIENT_ID>'
Congrats! You just made your first request to the Photoshop API.
- Automate your access token retrieval Go back to step 3 to obtain a fresh service token
You can find details on interacting with Adobe IMS API’s and authentication in general
Also known as the client_id
. You must additionally pass in your Adobe API key in the x-api-key
header field. You’ll automatically get a developer API key when you create your Adobe I/O Console Integration. After you've created your integration you can find your API key in the Overview
tab of your Integration
- The service will retry status codes of 429, 502, 503, 504 three times.
- You should only retry requests that have a 5xx response code. A 5xx error response indicates there was a problem processing the request on the server.
- You should implement an exponential back-off retry strategy with 3 retry attempts.
- You should not retry requests for any other response code.
We have not put a throttle limit on requests to the API at this time.
The typical workflow involves retrieving a PSD document manifest file via /documentManifest
(a JSON representation of the documents layer tree), followed by one or more calls to /documentOperations
to optionally edit the PSD and/or create new image renditions. Both endpoints are asynchronous so the response will contain the /status
endpoint to poll for job status and results
Clients can use assets stored on one of the following storage types:
- Adobe: by referencing the path to the files on Creative Cloud
- External: (like AWS S3) by using a presigned GET/PUT URL
- Azure: By generating a SAS (Shared Access Signature) for upload/download
- Dropbox: Generate temporary upload/download links using https://dropbox.github.io/dropbox-api-v2-explorer/
If you are making multiple edits to a PSD during the course of a user session it is your decision on how you want to track and store changes from one version of a PSD to another. Some clients will choose to refresh the document's JSON manifest by calling /documentManifest
again after each call to /documentOperations
. Other clients may choose to cache the changes locally and then make one final call to /documentOperations
with the original PSD and the accumulated changes requested by the user.
This is a partial list of currently supported features. Please also see the Release Notes for a list of added features
- General layer edits
- Edit the layer name
- Toggle the layer locked state
- Toggle layer visibility
- Move or resize the layer via it's bounds
- Delete layers
- Adjustment layers
- Add or edit an adjustment layer. The following types of adjustment layers are currently supported:
- Brightness and Contrast
- Exposure
- Hue and Saturation
- Color Balance
- Image/Pixel layers
- Add a new pixel layer, with optional image
- Swap the image in an existing pixel layer
- Shape layers
- Resize a shape layer via it's bounds
- Text layers
- Edit the text
- Change the font (See the
Fonts
section for more info) - Edit the font size
- Edit the text decoration (bold, italic, etc)
- Edit the text orientation (horizontal/vertical)
- Edit the paragraph alignment (centered, justified, etc)
- Edit the font weight
- Show artboard information in the JSON Manifest
- Create a new artboard from multiple input psd's
- Crop a PSD
- Resize a PSD
- Create a new PSD document
- Create a JPEG, TIFF or PNG rendition of various sizes
- Request thumbnail previews of all renderable layers
- Convert between any of the supported filetypes (PSD, JPEG, TIFF, PNG)
The Photoshop APIs currently support creating and editing of Text Layer with different fonts, character styles and paragraph styles.
The API's are documented here
We also have an example of making a simple text layer edit.
The APIs all use Postscript names.
The Photoshop APIs supports using fonts from two locations:
- Currently Installed Fonts
- Fonts the user is authorized to access via Typekit. (Currently only available for OAuth tokens, service token support is forthcoming...)
If your font is not included in either of these locations you must include an href to the font in your request. See the api docs for more information.
Font support is a work in progress.
The Photoshop APIs currently support creating and editing of Embedded Smart Objects. Support for Linked Smart Objects is forthcoming.
-
If the replacement image is of same size as of the original, the replaced smart object is placed in the bounding box of the original. If the replacement image is bigger or smaller than the original image, it fits into the original bounding box maintaining the aspect ratio. You can change the bounds of the replacement image by passing bounds parameters in the API call.
-
In order to replace an embedded smart object that is referenced by multiple layers you need to update all of those layers with the replacement image. Currently only same size image replacement is supported for this scenario.
-
Smart Object replacement is supported for file types,
psd
,tif
,jpeg
andpng
. We don't supportpdf
andai
files yet.
The API's are documented here
We also have an example of replacing a Smart Object within a layer.
Smart Object support is a work in progress.
- The API’s will open any PSD created with Photoshop 1.0 through the current release and this will always be true.
- When saving as PSD, the API’s will create PSD’s compatible with the current shipping Photoshop.
- In regards to “maximize compatibility” referenced in https://helpx.adobe.com/photoshop/using/file-formats.html#maximize_compatibility_for_psd_and_psb_files the API's default to “yes”
The API's are documented at https://adobedocs.github.io/photoshop-api-docs-pre-release/
The /documentManifest
api can take one or more input PSD's to generate JSON manifest files from. The JSON manifest is the tree representation of all of the layer objects contained in the PSD document. Using Example.psd, with the use case of a document stored in Adobe's Creative Cloud, a typical curl call might look like this:
curl -X POST \
https://image.adobe.io/pie/psdService/documentManifest \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>' \
-d '{
"inputs": [
{
"href":"files/Example.psd",
"storage":"adobe"
}
]
}'
This initiates an asynchronous job and returns a response containing the href to poll for job status and the JSON manifest.
{
"_links": {
"self": {
"href": "https://image.adobe.io/pie/psdService/status/63c6e812-6cb8-43de-8a60-3681a9ec6feb"
}
}
}
Using the job id returned from the previous call you can poll on the returned /status
href to get the job status and, upon success, the JSON Manifest
curl -X GET \
https://image.adobe.io/pie/psdService/status/63c6e812-6cb8-43de-8a60-3681a9ec6feb \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>'
Once your job completes (and does not report any errors) the status response will contain your document's JSON manifest along with other metadata about the input document. The JSON Manifest is further described in the api docs
{
"jobId":"63c6e812-6cb8-43de-8a60-3681a9ec6feb",
"outputs":[
{
"input":"files/Example.psd",
"status":"succeeded",
"created":"2018-08-24T23:07:36.8Z",
"modified":"2018-08-24T23:07:37.688Z",
"layers":[
{
"bounds":{
"height":64,
"left":12,
"top":1,
"width":39
},
"id":549,
"index":8,
"locked":false,
"name":"CompanyLogo",
"type":"smartObject",
"visible":true
},
{
"bounds":{
"height":153,
"left":31,
"top":334,
"width":197
},
"children":[
{
"bounds":{
"height":136,
"left":29,
"top":326,
"width":252
},
"text": {
"content":"Reset your customers’ expectations.",
"paragraphStyles":[
{
"alignment":"left"
}
],
"characterStyles":[{
"fontAvailable":true,
"fontName":"AdobeClean-Bold",
"fontSize":36,
"orientation":"horizontal",
}]
},
"id":412,
"index":6,
"locked":false,
"name":"Reset your customers’ expectations.",
"type":"textLayer",
"visible":true
},
{
"bounds":{
"height":67,
"left":30,
"top":452,
"width":230
},
"text":{
"content":"Get our retail experience article and infographic.",
"paragraphStyles":[{
"alignment":"left"
}],
"characterStyles":[{
"fontAvailable":true,
"fontName":"AdobeClean-Regular",
"fontSize":15,
"orientation":"horizontal",
}]
},
"id":676,
"index":5,
"locked":false,
"name":"Get our retail experience article and infographic.",
"type":"textLayer",
"visible":true
}
],
"id":453,
"index":7,
"locked":false,
"name":"Headline",
"type":"layerSection",
"visible":true
},
{
"bounds":{
"height":34,
"left":31,
"top":508,
"width":99
},
"id":762,
"index":3,
"locked":false,
"name":"CallToAction",
"type":"smartObject",
"visible":true
},
{
"bounds":{
"height":405,
"left":0,
"top":237,
"width":300
},
"id":751,
"index":2,
"locked":false,
"name":"BackgroundGradient",
"type":"layer",
"visible":true
},
{
"bounds":{
"height":515,
"left":-385,
"top":-21,
"width":929
},
"id":750,
"index":1,
"locked":false,
"name":"HeroImage",
"type":"smartObject",
"visible":true
},
{
"bounds":{
"height":600,
"left":0,
"top":0,
"width":300
},
"id":557,
"index":0,
"locked":false,
"name":"Background",
"type":"layer",
"visible":true
}
],
"document":{
"height":600,
"name":"Example.psd",
"width":300
}
}
],
"_links":{
"self":{
"href":"https://image.adobe.io/pie/psdService/status/8ec6e4f5-b580-41ac-b693-a72f150fec59"
}
}
}
Once you have your PSD file's JSON manifest you can use it to make layer and/or document level edits to your PSD and then generate new renditions with the changes. You can pass in either all or a subset of the JSON manifest to /documentOperations
as represented in the request body's options.layers
argument. In other words you can choose to pass options.layers
as a flat array of only the layers that you wish to act upon and can, if desired, leave out the rest.
The layer id or layer name are used by the service to identify the correct layer to operation upon in your PSD; Note that adding a new layer does not require the ID to be included, the service will generate a new layer id for you.
The add
, edit
, move
and delete
blocks are how you communicate that you'd like action taken on that particular layer object. Any layer block passed into the API that is missing the one of these attributes will be ignored.
In this example we will be editing a single text layer from Example.psd. We are only including a single layer object in the options.layers
array. We will be editing layer id 412 from the /documentManfest
examples above and making the following requests:
- NEW KEYWORD TO INDICATE AN EDIT: The
edit
key is included in layer id 412 - CHANGE LAYER POSITION: The layer's top and left will be set to 0,0
- CHANGE FONT SIZE: The font size will be reduced from 36 to 24 pixels
- CHANGE TEXT CONTENT: The text string will be changed to "Inspire your customers’ creativity."
- CHANGE LAYER NAME: The layer name will be changed to "Inspire your customers’ creativity."
- LOCK THE LAYER: The layer will be locked
- GENERATE RENDITION: We are requesting one new fullsize jpeg rendition
curl -X POST \
https://image.adobe.io/pie/psdService/documentOperations \
-H "Authorization: Bearer $token" \
-H "x-api-key: $apiKey" \
-d '{
"inputs":[
{
"href":"files/Example.psd",
"storage":"adobe"
}
],
"options":{
"layers":[
{
"edit":{}, // <--- NEW KEYWORD TO INDICATE AN EDIT
"bounds":{
"height":136,
"left":0, // <--- CHANGE LAYER POSITION
"top":0,
"width":252
},
"text":{
"content":"Inspire your customers’ creativity.", // <--- CHANGE TEXT CONTENT
"paragraphStyles":[{
"alignment":"left"
}],
"characterStyles":[{
"fontAvailable":true,
"fontName":"AdobeClean-Bold",
"fontSize":24, // <--- CHANGE FONT SIZE
"orientation":"horizontal",
}]
},
"id":412,
"index":6,
"locked":true, // <--- LOCK THE LAYER
"name":"Inspire your customers’ creativity.", // <--- CHANGE LAYER NAME
"type":"textLayer",
"visible":true
}
]
},
"outputs":[
{
"href":"files/Example.jpeg", // <--- GENERATE RENDITION
"storage":"adobe",
"width":0,
"type":"image/jpeg"
}
]
}'
This initiates an asynchronous job and returns a request body containing the href to poll for job status and requested rendition information.
{
"_links": {
"self": {
"href": "https://image.adobe.io/pie/psdService/status/8ad955af-e511-4c6f-845b-193c7bbba9b9"
}
}
}
Using the job id returned from the previous call you can poll on the returned /status
href to get the status for the edit job and each requested output
curl -X GET \
https://image.adobe.io/pie/psdService/status/8ad955af-e511-4c6f-845b-193c7bbba9b9 \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>'
And this will return a request body containing the job status for each requested output and eventually either errors or the hrefs to the requested outputs
{
"jobId":"8ad955af-e511-4c6f-845b-193c7bbba9b9",
"outputs":[
{
"input":"/files/Example.psd",
"status":"succeeded",
"created":"2018-01-04T12:57:15.12345:Z",
"modified":"2018-01-04T12:58:36.12345:Z",
"_links":{
"renditions":[
{
"href":"/files/Example.jpeg",
"storage":"adobe",
"type":"vnd.adobe.photoshop"
}
]
}
}
],
"_links":{
"self":{
"href":"https://image.adobe.io/pie/psdService/status/8ad955af-e511-4c6f-845b-193c7bbba9b9"
}
}
}
This example shows how you can add a new brightnessContrast adjustment layer to the top of your PSD. Things to note:
- NEW KEYWORD TO INDICATE AN ADDITION: The
add
key is included, along withinsertAbove
in the new layer object to indicate exactly where you want the new layer placed in the overall Manifest tree. - LAYER TYPE IS REQUIRED: The type indicates you want a new layer of type adjustment layer.
- LAYER ID AND INDEX ARE NOT PRESENT: The layer index and id are not supported for add operations. The index is implied by the objects position in the manifest tree and the ID will be generated by the service and returned to you in subsequent calls to
/documentManifest
curl -X POST \
https://image.adobe.io/pie/psdService/documentOperations \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>' \
-d '{
"inputs":[
{
"href":"files/Example.psd",
"storage":"adobe"
}
],
"options":{
"layers":[
{
"add":{ // <--- NEW KEYWORD TO INDICATE AN ADDITION
"insertAbove": {
"id": 549
} // <--- INDICATES THE LAYER SHOULD BE CREATED ABOVE ID 549
},
"adjustments":{
"brightnessContrast":{
"brightness":25,
"contrast":-40
}
},
"name":"NewBrightnessContrast",
"type":"adjustmentLayer" // <--- LAYER TYPE IS REQUIRED
}
]
},
"outputs":[
{
"href":"files/Example_Out.jpeg",
"storage":"adobe",
"type":"image/jpeg"
}
]
}'
In this example we want to replace the image in an existing pixel layer, the Hero Image layer in Example.psd. We are requesting the following:
- NEW KEYWORD TO INDICATE AN EDIT: The
edit
key is included to indicate we want to edit this layer - NEW KEYWORD TO INDICATE IMAGE REPLACEMENT INFO: The
layers.input
object is included to indicate where the replacement image can be found
curl -X POST \
https://image.adobe.io/pie/psdService/documentOperations \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>' \
-d '{
"inputs":[
{
"href":"files/Example.psd",
"storage":"adobe"
}
],
"options":{
"layers":[
{
"edit":{}, // <--- NEW KEYWORD TO INDICATE AN ADDITION
"input":{ // <--- NEW KEYWORD TO INDICATE IMAGE REPLACEMENT INFO
"href":"/files/newBackgroundImage.jpeg",
"storage":"adobe"
},
"bounds":{
"height":405,
"left":0,
"top":237,
"width":300
},
"id":751,
"index":2,
"locked":false,
"name":"BackgroundGradient",
"type":"layer",
"visible":true
}
]
},
"outputs":[
{
"href":"files/Example_Out.psd",
"storage":"adobe",
"type":"vnd.adobe.photoshop",
"overwrite":true
}
]
}
'
See the /renditionCreate
examples below as the format for the outputs
object in the request body is identical
In this example we want to swap the smart object in an existing embedded smart object layer, the Hero Image layer in Example.psd. We are requesting the following:
- The
edit
key is included to indicate we want to edit this layer - The
layers.input
object is included to indicate where the replacement image can be found - The
layers.smartObject
object is included to indicate specific information related to this image as SO
All the files used in the example are available in sample_files. You can download the files and put it in your CC account or any storage(AWS, Azure or Dropbox).
curl -X POST \
https://image.adobe.io/pie/psdService/documentOperations \
-H "Authorization: Bearer $token" \
-H "x-api-key: $apiKey" \
-d '{
"inputs":[
{
"href":"files/Example.psd",
"storage":"adobe"
}
],
"options":{
"layers":[
{
"edit":{},
"input":{
"href":"files/heroImage.png",
"storage":"adobe"
},
"smartObject" : {
"type" : "image/png",
"linked" : false
},
"attributes":{
"bounds":{
"height":515,
"left":-385,
"top":-21,
"width":929
}
},
"id":750,
"index":1,
"locked":false,
"name":"HeroImage",
"type":"smartObject",
"visible":true
}
]
},
"outputs":[
{
"href":"files/Example_Out.psd",
"storage":"adobe",
"type":"vnd.adobe.photoshop",
"overwrite":true
}
]
}
'
The /renditionsCreate
endpoint can take a number of input PSD files and generate new image renditions or a new PSD
In this example we are requesting two different outputs from our Example.psd input:
- Example.jpeg is a new JPEG rendition that has a width of 512 pixels
- Example.png is a new fullsize PNG rendition
curl -X POST \
https://image.adobe.io/pie/psdService/renditionCreate \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>' \
-d '{
"inputs":[
{
"href":"files/Example.psd",
"storage":"adobe"
}
],
"outputs":[
{
"href":"files/Example.jpeg",
"width": 512,
"storage":"adobe",
"type":"image/jpeg"
},
{
"href":"files/Example.png",
"storage":"adobe",
"type":"image/png"
}
]
}
'
This initiates an asynchronous job and returns a request body containing the href to poll for job status and requested rendition information.
{
"_links": {
"self": {
"href": "https://image.adobe.io/pie/psdService/status/de2415fb-82c6-47fc-b102-04ad651c5ed4"
}
}
}
Using the job id returned from the previous call you can poll on the returned /status
href to get the status for each requested output
curl -X GET \
https://image.adobe.io/pie/psdService/status/de2415fb-82c6-47fc-b102-04ad651c5ed4 \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>'
This will return a request body containing the job status for each requested output
{
"jobId":"de2415fb-82c6-47fc-b102-04ad651c5ed4",
"outputs":[
{
"input":"/files/Example.psd",
"status":"succeeded",
"created":"2018-01-04T12:57:15.12345:Z",
"modified":"2018-01-04T12:58:36.12345:Z",
"_links":{
"renditions":[
{
"href":"files/Example.jpeg",
"width": 512,
"storage":"adobe",
"type":"image/jpeg"
},
{
"href":"files/Example.png",
"storage":"adobe",
"type":"image/png"
}
]
}
}
],
"_links":{
"self":{
"href":"https://image.adobe.io/pie/psdService/status/de2415fb-82c6-47fc-b102-04ad651c5ed4"
}
}
}
In this example we are requesting new full size jpeg renditions from an input folder containing multiple PSD documents.
Note that the outputs
object is using file tokens, $FileName, to create new files with the same names as the input files found
curl -X POST \
https://image.adobe.io/pie/psdService/renditionCreate \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>' \
-d '{
"inputs":[
{
"href":"files/my_input_folder",
"storage":"adobe"
}
],
"outputs":[
{
"href":"files/$FileName.jpeg", // <--- THE $FileName TOKEN
"storage":"adobe",
"type":"image/jpeg",
}
]
}
'
The /smartObject
endpoint can take an input PSD file with an embedded smartobject and can replace with another smartobject.
This API is a simple API developed to ease the smartObject replacement workflow for an user.
This example shows how you can replace an embedded smart object
curl -H "Authorization: Bearer $token" \
-H "x-api-key: $api_key" \
-X POST \
https://image.adobe.io/pie/psdService/smartObject \
-d '{
"inputs": [
{
"href": "files/SOCreate.psd",
"storage": "adobe"
}],
"options": {
"layers": [{
"name": "New",
"input": {
"href": "files/jt-guitar.jpeg",
"storage": "adobe"
}
}
]
},
"outputs": [
{
"storage": "adobe",
"href": "files/SOedit.psd",
"type": "vnd.adobe.photoshop"
}
]}'
This example shows how you can create an embedded smart object
curl -H "Authorization: Bearer $token" \
-H "x-api-key: $api_key" \
-X POST \
https://image.adobe.io/pie/psdService/smartObject
-d '{
"inputs": [
{
"href": "files/SO.psd",
"storage": "adobe"
}],
"options": {
"layers": [{
"name": "New",
"add": {
"insertTop": true
},
"input": {
"href": "files/jt-drums.jpeg",
"storage": "adobe"
}
}
]
},
"outputs": [
{
"storage": "adobe",
"href": "files/SOCreate.psd",
"type": "vnd.adobe.photoshop"
}
]}'
The sample_code folder in this repo contains sample code for calling the Photoshop APIs.
Note that the sample code is covered by the MIT license.
There are a few limitations to the APIs you should be aware of ahead of time.
- Multi-part uploads and downloads are not yet supported
- The
/documentOperations
,/documentManifest
,/renditionCreate
and/smartObject
endpoints only support a single PSD input - Error handling is a work in progress. Sometimes you may not see the most helpful of messages
The file Example.psd is included in this repository if you'd like to experiment with these example calls on your own.
IMPORTANT: V1 of the Image Cutout service is being deprecated in favor of a new, more performant V2.
The Image Cutout API is powered by Sensei, Adobe’s Artificial Intelligence Technology, and Photoshop. The API's can identify the main subject of an image and produce two types of outputs. You can create a greyscale mask png file that you can composite onto the original image (or any other). You can also create a cutout where the mask has already composited onto your original image so that everything except the main subject has been removed.
Original | Mask | Cutout |
---|---|---|
The typical workflow involves making an API POST call to the endpoint https://image.adobe.io/sensei for which the response will contain a link to check the status of the asynchronous job. Making a GET call to this link will return the status of the job and, eventually, the links to your generated output.
The API's are documented at https://adobedocs.github.io/photoshop-api-docs/#api-Sensei
First be sure to follow the instructions in the Authentication section to get your token.
The /cutout
api takes a single input image to generate your mask or cutout from. Using Example.jpg, with the use case of a document stored in Adobe's Creative Cloud, a typical curl call might look like this:
curl -X POST \
https://image.adobe.io/sensei/cutout \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>' \
-d '{
"input":{
"storage":"adobe",
"href":"/files/images/Example.jpg"
},
"output":{
"storage":"adobe",
"href":"/files/output/cutout.png",
"mask":{
"format":"binary"
}
}
}'
This initiates an asynchronous job and returns a response containing the href to poll for job status and the JSON manifest.
{
"_links": {
"self": {
"href": "https://image.adobe.io/sensei/status/e3a13d81-a462-4b71-9964-28b2ef34aca7"
}
}
}
Using the job id returned from the previous call you can poll on the returned /status
href to get the job status
curl -X GET \
https://image.adobe.io/sensei/status/e3a13d81-a462-4b71-9964-28b2ef34aca7 \
-H 'Authorization: Bearer <auth_token>' \
-H 'Content-Type: application/json' \
-H 'x-api-key: <YOUR_API_KEY>'
Once the job is complete your successful /status
response will look similar to the response below; The output will have been placed in your requested location. In the event of failure the errors will be shown instead
{
"jobID": "e3a13d81-a462-4b71-9964-28b2ef34aca7",
"status": "succeeded",
"created": "2020-02-11T21:08:43.789Z",
"modified": "2020-02-11T21:08:48.492Z",
"input": "/files/images/Example.jpg",
"_links": {
"self": {
"href": "https://image-stage.adobe.io/sensei/status/e3a13d81-a462-4b71-9964-28b2ef34aca7"
}
},
"output": {
"storage": "adobe",
"href": "/files/output/cutout.png",
"mask": {
"format": "binary"
}
}
}
The workflow is exactly the same as creating an image cutout except you use the /mask
endpoint instead of /cutout
.
The typical workflow involves making a synchronous API call to the POST endpoint https://sensei.adobe.io/services/v1/predict for which the response will contain a link to the created mask file.
The API's are documented at https://adobedocs.github.io/photoshop-api-docs/#api-Sensei-ImageCutout_V1
The Adobe Lightroom APIs allow you to make Lightroom-like automated edits to image files.
The typical workflow involves making an API POST call to the endpoint https://image.adobe.io/lrService/ for which the response will contain a link to check the status of the asynchronous job. Making a GET call to this link will return the status of the job and, eventually, the links to your generated output.
The API's are documented at https://github.com/AdobeDocs/lightroom-api-docs