API
Asset (Image)

Asset

An asset is any image, video, audio, 3D model or other file that you want the platform to provide services for. You register assets, the platform provides services for those assets.

For historical reasons the API name of this resource class is vocab:Image, and images are still the most common scenario.

The services the platform provides include:

  • IIIF Image API service for image assets (register an image, the platform provides an image service)
  • Thumbnail creation for image assets
  • Transcoding audio and video assets to web friendly derivatives
  • Providing IIIF Authorisation Flow 2.0 Access control for any kind of asset
  • Storing related and derived files and metadata for an asset (OCR data, transcriptions, subtitles - anything you need to connect to your assets)

An example image asset:

{
  "@context": "https://dlcs.github.io/vocab/context/future.json",
  "@id": "https://api.dlcs.io/customers/2/spaces/5/images/b2921371x_0001.jp2",
  "@type": "vocab:Image",
  "id": "b2921371x_0001.jp2",
  "mediaType": "image/jp2",
  "space": 5,
 
  "origin": "https://s3-eu-west-1.amazonaws.com/example-bucket/digitised/b2921371x/v1/data/objects/b2921371x_0001.jp2",
  "created": "2023-07-20T09:56:39.0649160Z",
  "batch": "https://api.dlcs.io/customers/2/queue/batches/871143",
  "ingesting": false,
  "finished": "2023-07-20T09:56:50.5261830Z",
  "error": "",
 
  "duration": 0,
  "width": 8008,
  "height": 5754,
 
  "deliveryChannels": [
    {
      "@type": "vocab:DeliveryChannel",
      "channel": "iiif-img",
      "policy": "use-original"
    },
    {
      "@type": "vocab:DeliveryChannel",
      "channel": "thumbnail",
      "policy": "https://api.dlcs.io/customers/2/deliveryChannelPolicies/thumbnail/standard"
    },
    {
      "@type": "vocab:DeliveryChannel",
      "channel": "file",
      "policy": "none"
    }
  ],  
 
  "manifest": "https://dlcs.io/iiif-manifest/2/5/b2921371x_0001.jp2",
 
  "roles": [],
  "maxWidth": 0,
  "openFullMax": 0,
  "openMaxWidth": 0,
 
  "tags": [],
  "string1": "b2921371x",
  "string2": "b2921371x",
  "string3": "b2921371x",
  "number1": 0,
  "number2": 0,
  "number3": 0,
  
  "adjuncts": "https://api.dlcs.io/customers/2/spaces/5/images/b2921371x_0001.jp2/adjuncts",
 
  "metadata": "https://api.dlcs.io/customers/2/spaces/5/images/b2921371x_0001.jp2/metadata",
  "storage": "https://api.dlcs.io/customers/2/spaces/5/images/b2921371x_0001.jp2/storage",
 
  "usedBy": "https://api.dlcs.io/customers/2/spaces/5/images/b2921371x_0001.jp2/usedBy"
}

/customers/{customer}/spaces/{spaceId}/images/{id}

MethodLabelExpectsReturnsStatus
GETRetrieve an Asset-vocab:Image200 OK, 404 Not Found
PUTCreate or replace an assetvocab:Imagevocab:Image200 OK, 201 Created, 404 Not found
PATCHUpdate supplied field of assetvocab:Imagevocab:Image200 OK, 400 Bad request, 404 Not found
DELETEDelete an image-owl:Nothing200 OK, 404 Not Found

id

The model id of an asset. This is the part of an asset identifier within the space.

An asset API resource URL is of the form /customers/{customer}/spaces/{spaceId}/images/{modelId}, and the public facing URL of a delivered asset will be (or begin with, depending on whether the channel adds further path elements to the end) /{channel}/{customer}/{space}>/{id}, where {customer} may (for public facing URLs) be the customer.name string value or the integer customer identifier.

You can't update id for an existing asset (via PATCH), and if you create or update an asset via PUT, it is not required (if present, the platform will validate that it matches the last path element of the PUT URL). However, you MAY supply id on a POST to space.images, and you MUST supply id when registering assets in batches via the Queue. See Registering Assets for more details.

The platform will mint a GUID id if not supplied on a POST to space.images, but generally you should select your asset id values carefully, so that they are meaningful to you. You could use the asset file name (as in the above example), or an identifier associated with the file in a digital preservation system, or given to the asset during a digitisation workflow. Whatever you choose, it will form part of the public facing URL of the image service, or AV derivatives, or access file version.

domainrangereadonlywriteonly
vocab:Imagexsd:stringTrueFalse

mediaType

The media type (opens in a new tab) (also known as MIME type, or sometimes content type) of the asset. This identifies what kind of file the asset is. This is mandatory on newly registered assets. The platform does not inspect assets to determine this value (file format identification), or rely on file extensions to deduce types (your asset origins may not have file extensions). The platform uses the first type part of the mediaType (e.g., image, audio, text) to make processing decisions, in combination with the asset's deliveryChannels. It also provides the value when serving on the file deliveryChannel, and includes it in the output of the manifest linked resource.

domainrangereadonlywriteonly
vocab:Imagexsd:stringFalseFalse

Examples might be:

image/tiff
audio/mpeg
application/vnd.ms-excel
text/plain

space

The integer identifier of the customer Space. This is readonly on an asset except when sent in a batch to the queue (see registering assets), where a single batch of assets may be intended for different spaces. That is, you can set it on an asset that has yet to be given an @id within the system. After this point the value of space will always match the space part of the asset identifier. You do not need to supply it on API operations other than creation of assets to the queue, but if you do, it must match the expected space from the asset ID.

domainrangereadonlywriteonly
vocab:Imagexsd:integerTrue*False

origin

Origin endpoint from where the original image can be acquired (or was acquired). This is always a URI but is not necessarily an HTTP(S) URI - it could be SFTP, S3 or some other protocol, as long as the platform understands how to retrieve an asset from the URI and, where applicable, has an origin strategy configured to negotiate any access control protecting the asset.

For some assets the origin is only used once, at registration time. While the asset record retains the information, you don't need to maintain the asset at the origin URL indefinitely. For other assets the platform may retrieve the asset from the origin multiple times, and expects to be able to fetch it quickly when needed. This is npt the default behaviour - see origin strategy for details of optimised origins.

If an update of an asset modifies the value of origin, the asset will be re-processed (for example, a source image is replaced with a higher quality version). For some types of asset this action might modify other fields, such as the height and width if the asset is an image.

domainrangereadonlywriteonly
vocab:Imagexsd:string (a URI)FalseFalse

created

Date the asset was created (first known to the platform, rather than anything about the file at the origin).

domainrangereadonlywriteonly
vocab:Imagexsd:dateTimeTrueFalse

batch

The batch this image was ingested in (most recently). This is a link to the batch object created when this asset was last ingested via a queue.

An asset created directly, with POST to the parent space.images or a direct PUT, will not have a batch link.

Batches may also be archived, and an asset may lose the reference to its ingest batch after a long period (greater than one year).

domainrangereadonlywriteonly
vocab:Image🔗 vocab:BatchTrueFalse

/customers/{customer}/spaces/{spaceId}/images/{imageId}/{batchId}

MethodLabelExpectsReturnsStatus
GETRetrieve the asset's batch-vocab:Batch200 OK

ingesting

If true, the asset is still being processed by the platform and is not ready for public asset delivery via delivery channels. There is no limit to how many assets may be placed on a queue through batch submissions, so an asset can be in the ingesting state for a long period of time. The platform scales up to process large queue backlogs when they arise.

domainrangereadonlywriteonly
vocab:Imagexsd:booleanTrueFalse

finished

Date the asset left the ingesting state. This value will be cleared if the asset is submitted for reprocessing (an asset can't have a finished value and have ingesting=true at the same time).

domainrangereadonlywriteonly
vocab:Imagexsd:dateTimeTrueFalse

error

A string message from any error(s) encountered the last time this asset was processed. If re-processed the value will be cleared.

domainrangereadonlywriteonly
vocab:Imagexsd:stringTrueFalse

duration

The length in milliseconds of a time-based asset. This will be set by the platform when the asset is processed.

Is this only allowed on audio/* and video/* mediaType? Or is that too restrictive? Is the customer allowed to specify it? Can we always determine it?

domainrangereadonlywriteonly
vocab:Imagexsd:integerFalseTrue

width

The width in pixels of a bitmap-based image. This will be set by the platform when the asset is processed.

domainrangereadonlywriteonly
vocab:Imagexsd:integerFalseTrue

height

The height in pixels of a bitmap-based image. This will be set by the platform when the asset is processed.

domainrangereadonlywriteonly
vocab:Imagexsd:integerFalseTrue

deliveryChannels

Delivery channels specify the way(s) in which you want the platform to make your assets available.

It is possible for an asset to have no delivery channels, in which case it is known to the platform but not yet served.

You can assign delivery channels explicitly at registration time, or you can omit the property when registering and allow the platform to assign default delivery channels based on the values of customer.defaultDeliveryChannels and space.defaultDeliveryChannels. An asset resource returned by API will always list delivery channels.

See Delivery Channels for full details.

domainrangereadonlywriteonly
vocab:ImageArray of vocab:DeliveryChannelFalseFalse

Not that the value of this property is an inline array of vocab:DeliveryChannel, not a link to a collection.

manifest

A link to a IIIF Presentation 3 manifest that provides the URLs and additional information for all the outputs of the delivery channels, and any adjuncts you have registered (or that the platform has created).

domainrangereadonlywriteonly
vocab:Image🔗 iiif:ManifestFalseFalse

usedBy 🆕

This asset may be used by one or more Manifests that the platform is also managing and serving. Those manifests link to this asset, and this asset provides the reverse linking, allowing you to keep track of where the asset is being used.

Typically, an asset is used in only one Manifest, but not always.

The returned collection cannot include Manifests that the platform doesn't know about! There could be many third party Manifests also referencing an image service generated from this asset, but you have no way of knowing about them.

domainrangereadonlywriteonly
vocab:Image🔗 iiif:CollectionTrueFalse

/customers/{customer}/spaces/{spaceId}/images/{imageId}/{batchId}

MethodLabelExpectsReturnsStatus
GETRetrieve a IIIF Collection of Manifests that this asset is used in-iiif:Collection200 OK

roles

An array of Role URIs. The roles a user needs to have to access the output of a delivery channel for this asset. A user acquires roles by interacting with an Auth Service.

Roles are always URIs of the form {...}/customers/{customer}/roles/{roleId}, i.e., members of the customer.roles collection.

See Access Control for a general discussion. Note that for image assets, setting positive values for openFullMax and openMaxWidth allows a user to see images below configured sizes without roles.

domainrangereadonlywriteonly
vocab:ImageArray of 🔗 vocab:RoleFalseFalse

Example:

   "roles": [
    "https://api.dlcs.io/customer/2/roles/staff",
    "https://api.dlcs.io/customer/2/roles/reading-room",
   ]

maxWidth

Restricts the maximum permitted pixel response as defined in the Image API.

domainrangereadonlywriteonly
vocab:Imagexsd:integerFalseTrue

The platform only supports maxWidth, not maxHeight or maxArea.

The IIIF Image API specification (opens in a new tab) says "If maxWidth is specified and maxHeight is not, then clients should infer that maxHeight = maxWidth." In the IIIF Cloud Services platform, maxWidth therefore defines a square bounding box. So you can't get a 100 w x 1000 h image if maxWidth is 100.

As well as governing the allowed pixel responses from the level 2 iiif-img delivery channel, this value is also considered by the thumbnail delivery channel. The platform will not generate thumbnails larger than the maxWidth limit even if the policy defines them.

If the image has roles, and openFullMax and openMaxWidth are both 0, no thumbnails will be produced (this behaviour is not dependent on maxWidth but on the requirement that nothing on the thumbnail delivery channel is subject to access control; if you offer thumbs they must be accessible anonymously).

See Size Restrictions for examples of the effects of the maxWidth, openFullMax and openMaxWidth properties.

openFullMax

Only applies when an image has roles, and the image request region is /full/. This value is ignored if the image does not have roles (it is not considered an error, as you may vary roles for other reasons). Pixel requests on the iiif-img delivery channel whose region is /full/ and whose size fits a bounding square openFullMax on an edge are permitted whether the use has any of the roles or not (therefore also for anonymous users).

domainrangereadonlywriteonly
vocab:Imagexsd:integerFalseTrue

On the thumbnail delivery channel, thumbs will be generated by the policy as long as their resulting sizes are equal to or less than the bounding square defined by openFullMax.

This setting allows an access-controlled image to have open thumbnails. Typical settings are low - e.g., 200 or 400 - sizes suitable for thumbnails but not for reading text in an image.

A value of 0 or less than 0 is considered unset.

See Size Restrictions for examples of the effects of the maxWidth, openFullMax and openMaxWidth properties.

openMaxWidth

Only applies when an image has roles, and for any region, including /full/.

domainrangereadonlywriteonly
vocab:Imagexsd:integerFalseTrue

This setting allows Image API tiles for deep zoom to be served to any user - anonymous, or without a matching role. An anonymous user can deep zoom, but not download a high resolution image. For this reason it is recommended that the value of this setting is a power of 2, e.g., 512, so that it matches an optimised tile size for deep zoom.

This setting does not (and cannot) prevent a user from stitching multiple individual image tiles into a single large image, or taking a screen grab of rendered tiles in a viewer, but does prevent sharing of single IIIF Image API URLs for large images.

When an image has roles and has a value greater than zero for openMaxWidth, the iiif-img delivery channel provides an info.json with a probe service. The probe service will return status: 401 for a user without any matching role, but will also offer a substitute as defined in the IIIF Authorization Flow specification.

If the image has an Image Service endpoint of https://dlcs.io/iiif-img/2/99/my-image, the probe response for an unauthorised user is:

{
  "@context": "http://iiif.io/api/auth/2/context.json",
  "id": "https://dlcs.io/probe/2/99/my-image",
  "type": "AuthProbeResult2",
  "status": 401,
  "substitute": {
    "id": "https://dlcs.io/iiif-img/2/99/my-image/substitute",
    "type": "ImageService3"
  }
}

The substitute image service at https://dlcs.io/iiif-img/2/99/my-image/substitute is for the same source image, but has no access control. However, it does have a maxWidth of openMaxWidth (e.g., 512).

The expected behaviour of a IIIF client is to show the substitute, and offer the user the option to log in to access the original image service.

If an image has both maxWidth and openMaxWidth, the first, access controlled image has a maxWidth of maxWidth and the second, open image service has a maxWidth of openMaxWidth. This feature doesn't make much sense unless maxWidth is either 0 or is greater than openMaxWidth, but it's not an error if maxWidth <= openMaxWidth (again, you may be updating different things at different times).

On the thumbnail delivery channel, thumbnails will be created up to the limit defined by maxWidth or openMaxWidth, whichever is lower (unless maxWidth is 0).

A value of 0 or less than 0 is considered unset.

See Size Restrictions for examples of the effects of the maxWidth, openFullMax and openMaxWidth properties.

tags

An array of string tags that can be used as parameters in asset queries or named queries.

domainrangereadonlywriteonly
vocab:ImageArray of xsd:stringFalseFalse

Assets can automatically be given tags if their parent space has values in its defaultTags property, and the asset is first registered with no supplied tags field. If you need to specify that an asset has no tags (in a space with defaultTags), or you want to clear tags from an asset, supply an empty array.

string1

A metadata value that can be used as a parameter in asset queries or named queries. The platform makes no use of these values other than in queries - it is for your applications to give them meaning.

domainrangereadonlywriteonly
vocab:Imagexsd:stringFalseFalse

string2

A metadata value that can be used as a parameter in asset queries or named queries. The platform makes no use of these values other than in queries - it is for your applications to give them meaning.

domainrangereadonlywriteonly
vocab:Imagexsd:stringFalseFalse

string3

A metadata value that can be used as a parameter in asset queries or named queries. The platform makes no use of these values other than in queries - it is for your applications to give them meaning.

domainrangereadonlywriteonly
vocab:Imagexsd:stringFalseFalse

number1

A metadata value that can be used as a parameter in asset queries or named queries. The platform makes no use of these values other than in queries - it is for your applications to give them meaning.

domainrangereadonlywriteonly
vocab:Imagexsd:integerFalseFalse

number2

A metadata value that can be used as a parameter in asset queries or named queries. The platform makes no use of these values other than in queries - it is for your applications to give them meaning.

domainrangereadonlywriteonly
vocab:Imagexsd:integerFalseFalse

number3

A metadata value that can be used as a parameter in asset queries or named queries. The platform makes no use of these values other than in queries - it is for your applications to give them meaning.

domainrangereadonlywriteonly
vocab:Imagexsd:integerFalseFalse

adjuncts

A link to a collection of resources stored in the platform and associated with the asset. These can be any resource; you can use the platform as storage for related files, and have the platform generate IIIF seeAlso metadata in named queries and other manifests. for See Adjuncts for details.

domainrangereadonlywriteonly
vocab:Image🔗 hydra:CollectionTrueFalse

HTTP operations

/customers/{customer}/spaces/{space}/images/{imageId}/adjuncts

MethodLabelExpectsReturnsStatus
GETLists all the adjuncts associated with the Asset-🔗 hydra:Collection (of multiple types)200 OK
POSTAdd a new adjunct by supplying an origin, OR by instructing the platform to create the adjunct (e.g., via OCR).A valid adjunct resource*a valid adjunct resource*201 Created

*See Adjuncts for details.

metadata

A link to delivery-channel-specific information generated as a byproduct of the asset registration process. Currently this is only available for the iiif-av delivery channel.

The information returned from this endpoint is not considered part of the public platform API, but is made available for diagnostics.

domainrangereadonlywriteonly
vocab:Image🔗 (undefined)TrueFalse

/customers/{customer}/spaces/{spaceId}/images/{imageId}/metadata

MethodLabelExpectsReturnsStatus
GETRetrieve asset processing metadata, if available-(undefined)200 OK, 404 Not Found

storage

A link to an object that provides storage usage information about this individual asset.

domainrangereadonlywriteonly
vocab:Image🔗 vocab:ImageStorageTrueFalse

/customers/{customer}/spaces/{spaceId}/images/{imageId}/storage

MethodLabelExpectsReturnsStatus
GETGet storage usage for this object-vocab:ImageStorage200 OK, 404 Not Found

See Storage for more information.

This needs to be generalised to report on usage per delivery channel.

reingest

A POST-only endpoint. a POST to this resource with an empty body will make the platform re-process the asset - typically (for an image), re-fetching the asset from origin, re-making thumbnails and so on.

Often you don't need to do this explicitly - a property update like changing the value of origin will trigger a re-process automatically. But sometimes, the platform has no way of knowing that an asset needs re-processing (for example, changing the file at the same origin URL to a higher resolution version).

MethodLabelExpectsReturnsStatus
POSTForce platform to re-process asset-vocab:Image200 OK, 404 Not Found

Need to determine what happens when a thumbnail policy is updated.



(First draft) Version 1

NB the API asset does not have a property called maxWidth, it has these two instead:

max

(integer)

maxBehaviour

(string from vocab) - one of maxWidth, substitute, thumbnail.

roles

(as normal, connected to role providers / auth services)

The effect of setting max depends on what you set maxBehaviour to:

  • maxWidth: this is independent of roles the image might have. If the image has role(s), you need a role to see the image - at any size. And maxWidth applies equally to images with roles and without. You can't request an image above maxWidth (regular IIIF behaviour) regardless of whether you have a role or not. If the image has roles it offers auth services for those roles, and offers no substitute.
  • substitute: the effect is "Anyone can see a request up to maxWidth but you need a role to see higher". The implementation is complex. For an asset /2/5/image.tif, the published info.json at /2/5/image.tif/info.json has a probe service that returns status: 401. This info.json has no maxWidth property. Its probe service provides a substitute at /2/5/image.tif/substitute which does not have auth services - it's open - but DOES have a maxWidth of (max).
  • thumbnail: this only applies to images with roles, and means that even though you can't generally see the image without a role - the probe service says 401 - if you actually make a /full/ size request whose longest edge is less than or equal to (max), the platform will return an image with HTTP 200. Any non-full request, or any size request over (max), will be unauthorised.

Notes:

  • thumbnail is the same as current maxUnauthorised. Note that for this choice it's not a width, it's a bounding box - like maxUnauthorised.
  • In all cases, if there is a thumbnail delivery channel, public thumbs (which are always /full/) are only generated for sizes that can be seen without auth - keeping with our policy of never having auth on thumb services.

What about the scenario where you want to allow full thumbs up to 400 px, but still impose a maxWidth of 512 even for authed users? This is like maxWidth AND thumbnail but needs two values. Do we just not bother with that?

Or have a fourth behaviour:

  • maxWidthWithOpenThumbs (or a better name) where regardless of roles we generate open thumbs up to (max). Youi could control the sizes through the delivery channel policy - e.g., maxWidth is 512, so in theory a 500px thumb would be allowed, but the thumbnail channel policy has 100,200,400 - so only those are offered.

{
  "@context": "https://dlcs.github.io/vocab/context/future.json",
  "@id": "https://api.dlcs.io/customers/2/spaces/5/images/b2921371x_0001.jp2",
  "@type": "vocab:Image",
  
  "max": 400,
  "maxBehaviour": "maxWidth"
}
touched 2025-09-23T12:04:54