Digital Asset CRUD APIĀ 

Updates have been made to include organization ID in the URL path as of April 2017. This is the preferred method, but previously-working methods will continue to function as expected.

List of operations

The digital asset API is a REST API supporting the following actions and endpoints:

  • CREATE an asset - POST https://app.salsify.com/api/v1/orgs/<org_ID>/digital_assets
  • READ an asset - GET https://app.salsify.com/api/v1/orgs/<org_ID>/digital_assets/<asset_id>
  • UPDATE an asset - PUT https://app.salsify.com/api/v1/orgs/<org_ID>/digital_assets/<asset_id>
  • DELETE an asset - DELETE https://app.salsify.com/api/v1/orgs/<org_ID>/digital_assets
  • REFRESH an asset - POST https://app.salsify.com/api/v1/orgs/<org_ID>/digital_assets/refresh

<asset_id> should be replaced with the unique Salsify identifier for each digital asset. 

<org_id> should be replaced by the organization ID which is unique to each Salsify app instance. The org ID can be found after /orgs/ in the URL path for your Salsify organization, eg. in https://app.salsify.com/app/orgs/9-99999-9999-9999-9999-999999999/products the org ID is 9-99999-9999-9999-9999-999999999.

CREATE

POST /api/v1/orgs/<org_ID>/digital_assets

Required Parameters

  • salsify:source_url - An HTTP(S) URL of a public image on the Internet.

Optional Parameters

  • salsify:id - The identifier to use for the asset. A randomly generated ID is assigned if not specified.
  • salsify:name - A name to use for the asset. The filename is used if not specified.
  • Additional metadata properties can be specified as name/value pairs. They cannot start with 'salsify:'.

Sample 1

Request:

{ 
    "salsify:id": "yoda.png",
    "salsify:source_url": "http://img1.wikia.nocookie.net/__cb20150206140125/starwars/images/d/d6/Yoda_SWSB.png",
    "Foo": "Bar"
}

Response:

{ 
    "salsify:id": "yoda.png",
    "salsify:source_url": "http://img1.wikia.nocookie.net/__cb20150206140125/starwars/images/d/d6/Yoda_SWSB.png",
    "salsify:status": "in_progress",
    "Foo": "Bar",
}

Sample 2

Request:

{
  "salsify:source_url": "http://img1.wikia.nocookie.net/__cb20150206140125/starwars/images/d/d6/Yoda_SWSB.png"
}

Response:

{
  "salsify:id": "asdsdfhdahfdgsd",
  "salsify:source_url": "http://img1.wikia.nocookie.net/__cb20150206140125/starwars/images/d/d6/Yoda_SWSB.png",
  "salsify:status": "in_progress"
}

Valid statuses are:

  • complete - Asset has been processed successfully and automatic metadata is now available.
  • in_progress - Asset is in process and automatic metadata is not yet available.
  • failed - Asset failed to download. salsify:failure_reason will be specified in this case with more information.

Creating multiple assets

Multiple assets can be created by sending a POST request with an array. Each array element must contain all required parameters. Like all bulk requests, the operation will only succeed if all operations are performed successfully. For instance, multiple assets might be created with the following request:

[
  {
    "salsify:id": "yoda.png",
    "salsify:source_url": "http://img1.wikia.nocookie.net/__cb20150206140125/starwars/images/d/d6/Yoda_SWSB.png"
  },
  {
    "salsify:source_url": "http://feelgrafix.com/data_images/out/28/958594-yoda.jpg"
  }
]

The response (if successful) is an array of the created assets in the format defined above for a single asset.

READ

GET /api/v1/orgs/<org_ID>/digital_assets/<asset_id>

Sample Request

GET /api/v1/orgs/<org_ID>/digital_assets/yoda.png

Sample Response

{
  "salsify:id": "yoda.png",
  "salsify:source_url": "http://img1.wikia.nocookie.net/__cb20150206140125/starwars/images/d/d6/Yoda_SWSB.png",
  "salsify:url": "http://images.salsify.com/image/upload/vsrgfytrpsa1r7d4dwkx.jpg",
  "salsify:filename": "Yoda_SWSB.png",
  "salsify:is_primary_image": true,
  "salsify:created_at": "2015-07-07T13:03:54.495Z",
  "salsify:updated_at": "2015-07-07T13:03:54.495Z",
  "salsify:bytes": 22222,
  "salsify:width": 123,
  "salsify:height": 123,
  "salsify:resource_type": "image",
  "salsify:format": "png",
  "salsify:status": "complete"
}

Read Multiple Assets

Multiple assets can be read by sending a REPORT request with an array. Each array element must contain all required parameters. Like all bulk requests, the operation will only succeed if all operations are performed successfully.

Results will include null array entries for any digital assets that are not found.

Example request:

REPORT /api/v1/orgs/<org_ID>/digital_assets
{
 ids: [
 "8aab51dd8901680d75cf63a1fad54c9a18535f94"
 "missing-id",
 "3419970ffb9988a81b9dc19735626ac430e1fcde"
 ]
}

Example response:

[
 {
 "salsify:id":"8aab51dd8901680d75cf63a1fad54c9a18535f94",
 "salsify:url":"http://res.cloudinary.com/salsify/image/upload/ltxmqunjjyvdmanxl07r.jpg",
 "salsify:source_url":"https://cnet2.cbsistatic.com/img/25gGPtxEkFGfNdGlBhkfr1GYwvg=/770x433/2010/10/22/6a9bbef4-cc2e-11e2-9a4a-0291187b029a/ricoh-caplio-r5_1.jpg",
 "salsify:name":"ricoh-caplio-r5_1.jpg",
 "salsify:created_at":"2017-03-03T17:06:37.989Z",
 "salsify:updated_at":"2017-03-03T17:06:45.113Z",
 "salsify:status":"completed",
 "salsify:asset_height":433,
 "salsify:asset_width":770,
 "salsify:asset_resource_type":"image",
 "salsify:filename":"ricoh-caplio-r5_1.jpg",
 "salsify:bytes":38603,
 "salsify:format":"jpg",
 "salsify:etag":"e4d29523c35ef921a2e7e744f87cbfef",
 "salsify:system_id":"s-11e1909e-35a2-4417-8c8d-8a8100a7751a"
 },
 null,
 {
 "salsify:id":"3419970ffb9988a81b9dc19735626ac430e1fcde",
 "salsify:url":"http://res.cloudinary.com/salsify/image/upload/thfogjeczehlhqghvyww.jpg",
 "salsify:source_url":"http://www3.pcmag.com/media/images/168925-canon-powershot-a550.jpg?thumb=y&width=275&height=219",
 "salsify:name":"168925-canon-powershot-a550.jpg",
 "salsify:created_at":"2017-03-03T17:06:37.989Z",
 "salsify:updated_at":"2017-03-03T17:06:47.216Z",
 "salsify:status":"completed",
 "salsify:asset_height":219,
 "salsify:asset_width":275,
 "salsify:asset_resource_type":"image",
 "salsify:filename":"168925-canon-powershot-a550.jpg?thumb=y&width=275&height=219",
 "salsify:bytes":11946,
 "salsify:format":"jpg",
 "salsify:etag":"1a122c5c5eec479a72b78d5a489f852f",
 "salsify:system_id":"s-c573d9bf-df47-43df-ae29-96d740859b98"
 }
]

UPDATE

PUT /api/v1/orgs/<org_ID>/digital_assets/<asset_id>

Required Parameters

Optional Parameters

  • salsify:source_url - An HTTP(S) URL of a public image on the Internet. Will update the asset and all automatically generated metadata if specified. Will not update id or name.
  • salsify:id - The identifier of the asset. Will update the asset's ID if specified.
  • salsify:name - A name to use for the asset. Will update the asset's name if specified.
  • Additional metadata properties can be specified as name/value pairs. They cannot start with 'salsify:'. Any specified properties will overwrite the existing values for those properties. Any properties not mentioned will be left as is.

Sample 1

Request: PUT /api/v1/orgs/<org_ID>/digital_assets/yoda.png

{
  "Foo": "Baz",
  "Coffee": ["Dunkin' Donuts", "Starbucks"]
}

Response to GET /api/v1/orgs/<org_ID>/digital_assets/yoda.png

{
  "salsify:id": "yoda.png",
  "salsify:source_url": "http://img1.wikia.nocookie.net/__cb20150206140125/starwars/images/d/d6/Yoda_SWSB.png",
  "salsify:name": "Yoda_SWSB.png",
  "salsify:url": "http://images.salsify.com/image/upload/vsrgfytrpsa1r7d4dwkx.jpg",
  "salsify:filename": "Yoda_SWSB.png",
  "salsify:is_primary_image": true,
  "salsify:created_at": "2015-07-07T13:03:54.495Z",
  "salsify:updated_at": "2015-07-07T13:03:54.495Z",
  "salsify:bytes": 22222,
  "salsify:width": 123,
  "salsify:height": 123,
  "salsify:resource_type": "image",
  "salsify:format": "png",
  "salsify:status": "complete",
  "Foo": "Baz",
  "Coffee": ["Dunkin' Donuts", "Starbucks"]
}

Sample 2

Request: PUT /api/v1/orgs/<org_ID>/digital_assets/yoda.png

{
  "salsify:source_url": "http://feelgrafix.com/data_images/out/28/958594-yoda.jpg"
}

Response to GET /api/v1/orgs/<org_ID>/digital_assets/yoda.png

{
  "salsify:id": "yoda.png",
  "salsify:source_url": "http://feelgrafix.com/data_images/out/28/958594-yoda.jpg",
  "salsify:name": "Yoda_SWSB.png",
  "salsify:is_primary_image": true,
  "salsify:created_at": "2015-07-07T13:03:54.495Z",
  "salsify:updated_at": "2015-07-07T13:03:54.495Z",
  "salsify:status": "in_progress",
  "Foo": "Bar"
}

Updating multiple assets

Multiple assets can be updated at once by sending a PUT request with an array to /api/v1/orgs/<org_ID>/digital_assets. Each array element must contain a salsify:id parameter. Like all bulk requests, the operation will only succeed if all operations are performed successfully. Note that salsify:id cannot be updated in bulk.

DELETE

DELETE /api/v1/orgs/<org_ID>/digital_assets
Assets can be deleted singly or in bulk. The format for a single refresh is: ["ID_FOR_ASSET"]

For example:

curl -X DELETE -H "Accept: application/json" -H "Content-Type: application/json" -H Authorization: 
Bearer <your auth token here> -d '["box:41130282306"]' https://app.salsify.com/api/v1/orgs/<org_ID>/digital_assets/

The bulk format is the same as the single, each delete is an entry in an array.

[ "ID_FOR_ASSET_1","ID_FOR_ASSET_2", ... ]

Delete multiple assets

Multiple assets can be deleted at once by sending a DELETE request with an array to /api/v1/orgs/<org_ID>/digital_assets. Like all bulk requests, the operation will only succeed if all operations are performed successfully.

REFRESH

Currently Salsify does not re-download images if they come from the same url. So if you were to update an image on a DAM and try to import that image into salsify with the same url the product currently has it won't change the image and keep the old image instead.

POST /api/v1/orgs/<org_ID>/digital_assets/refresh

Required Parameters

  • salsify:id - The Salsify identifier of the asset. 

Assets can be refreshed singly or in bulk. The format for a single refresh is: ["ID_FOR_ASSET"]

For example:

curl -X POST -H "Accept: application/json" -H "Content-Type: application/json" -H Authorization: 
Bearer <your auth token here> -d '["box:41130282306"]' https://app.salsify.com/api/v1/orgs/<org_ID>/digital_assets/refresh

The bulk format is the same as the single, each refresh is a an entry in an array.
[ "ID_FOR_ASSET_1","ID_FOR_ASSET_2", ... ]

This takes a max number of 100 assets per request in JSON. To get the existing digital assets and the products they correspond to, you need a json export channel with the properties that relate to the digital assets.

Sample Code

require 'json'
require 'rest-client'
require 'aws-sdk'
require 'csv'

SALSIFY_AUTH_TOKEN = 'REPLACEME'
SALSIFY_BASE_URL = 'https://app.salsify.com'
 
AWS_ACCESS_KEY_ID = 'REPLACEME'
AWS_SECRET_ACCESS_KEY = 'REPLACEME'
AWS_S3_REGION = 'us-east-1'
AWS_S3_BUCKET = 'REPLACEME'
AWS_S3_PREFIX = '' # Prefix for all uploads to S3 (e.g. 'salsify-images')

 
 
def array_wrap(object)
  if object.nil?
    []
  elsif object.respond_to?(:to_ary)
    object.to_ary || [object]
  else
    [object]
  end
end
 
s3 = Aws::S3::Resource.new(
  credentials: Aws::Credentials.new(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY),
  region: AWS_S3_REGION
)
 
objs = ARGV.map do |file|
  obj = s3.bucket(AWS_S3_BUCKET).object("#{AWS_S3_PREFIX}/#{File.basename(file)}")
  obj.upload_file(file) or raise "Failure uploading #{file} to S3"
  print "."
  obj
end
 
assets = []
 
objs.each_slice(100) do |batch|
  request = batch.map do |obj|
    # Pre-signed URLs will expire in 12 hours
    url = obj.presigned_url(:get, expires_in: 43200)
    { "salsify:id" => File.basename(obj.key) }
  end
 
  response = RestClient.post("#{SALSIFY_BASE_URL}/api/v1/orgs/<org_ID>/digital_assets", request.to_json, Authorization: Bearer <your auth token here>, content_type: :json, accept: :json)
 
  if response.code == 201
    assets += array_wrap(JSON.parse(response.to_str))
  else
    raise "Failure creating digital assets: #{response.code}\n\n#{response.to_str}"
  end
end
 
puts "\nCreated #{assets.length} digital assets. CSV of created assets:\n\n"
csv = CSV.generate do |csv|
  csv