Skip to content

Customer

A customer represents your account on the platform. You only have access to one customer, so it is your effective entry point for the API. While the root entry point provides links to resources and policies that anyone can use, your Customer object provides links to your assets and policy configurations. The only interaction you can have with your Customer resource directly is updating the display name, but it provides link properties to Collections of all the other resources.

{
"@context": "https://dlcs.github.io/vocab/context/future.json",
"@id": "https://api.dlcs.example/customers/2",
"@type": "vocab:Customer",
"name": "example-customer",
"displayName": "Example Customer",
"created": "2020-01-17T15:36:58.6023600Z",
"spaces": "https://api.dlcs.example/customers/2/spaces",
"iiif": "https://api.dlcs.example/customers/2/iiif",
"allImages": "https://api.dlcs.example/customers/2/allImages",
"originStrategies": "https://api.dlcs.example/customers/2/originStrategies",
"deliveryChannelPolicies": "https://api.dlcs.example/customers/2/deliveryChannelPolicies",
"defaultDeliveryChannels": "https://api.dlcs.example/customers/2/defaultDeliveryChannels",
"namedQueries": "https://api.dlcs.example/customers/2/namedQueries",
"queue": "https://api.dlcs.example/customers/2/queue",
"portalUsers": "https://api.dlcs.example/customers/2/portalUsers",
"storage": "https://api.dlcs.example/customers/2/storage",
"keys": "https://api.dlcs.example/customers/2/keys",
"customHeaders": "https://api.dlcs.example/customers/2/customHeaders"
}

/customers/{customer}

MethodLabelExpectsReturnsStatus
GETRetrieve a customer record-vocab:Customer200 OK, 404 Not Found
PATCHEdit a customer recordvocab:Customervocab:Customer200 OK, 404 Not Found

Only the fields name and displayName are editable.

The URL-friendly name of the customer, can be used in public-facing URLs (such as image requests, or IIIF info.json requests) as a slug or path element rather than the integer customerId.

domainrangereadonlywriteonly
vocab:Customerxsd:stringFalseFalse

For API operations, the integer customer identifier must only be used.

From the sample customer above, if they had an image with this API resource URL:

https://api.dlcs.example/customers/2/spaces/5/images/my-image

Then the IIIF Image Service is available on either of these URLs:

https://dlcs.example/iiif-img/2/5/my-image
https://dlcs.example/iiif-img/example-customer/5/my-image

But the following would be INVALID for API use:

// INVALID!
https://api.dlcs.example/customers/example-customer/spaces/5/images/my-image

The display name of the customer. Can contain any valid Unicode characters.

domainrangereadonlywriteonly
vocab:Customerxsd:stringFalseFalse

When the customer was added to this platform instance.

domainrangereadonlywriteonly
vocab:Customerxsd:dateTimeTrueFalse

A link to a paged Collection of all the Space resources associated with your customer. A space allows you to organise assets (like folders), and specify different defaults for assets per space.

See Space.

domainrangereadonlywriteonly
vocab:Customer🔗 hydra:CollectionTrueFalse

/customers/{customer}/spaces

MethodLabelExpectsReturnsStatus
GETList all your spaces-🔗 hydra:Collection (of vocab:Space)200 OK
POSTAdd a new space. The platform will assign the identifier (integer) to the space, using the next available value.vocab:Spacevocab:Space201 Created,
400 Bad request,
409 Conflict

At the very least the request payload should provide a name for the Space:

POST /customers/{customer}/spaces
{ "name": "My new space" }
field
nameREQUIRED
  • Do not supply an id or @id field.
  • If name conflicts with an existing Space, the response will be HTTP 409.

See also the PUT and DELETE operations on Space itself.

A query endpoint for retrieving full assets from any of your spaces, using asset query syntax with HTTP GET. It’s unlikely you would use this endpoint without additional query data, but if you do it will simply return a paged hydra:Collection of all your assets across all spaces. It can also be used as a query endpoint retrieving full assets from any of your spaces, given just the internal identifier or a query, with HTTP POST.

domainrangereadonlywriteonly
vocab:Customer🔗 hydra:CollectionFalseFalse
MethodLabelExpectsReturnsStatus
GETAppend a query parameter to return matching assets across all spaces.(no body, but usually a query string)hydra:Collection200 OK
POSTSubmit the set of identifiers you want full information forhydra:Collectionhydra:Collection200 OK
GET /customers/2/allImages

returns a paged collection of all assets across all spaces.

GET /customers/2/allImages?q={"string1":"my-value"}
or
GET /customers/2/allImages?string1=my-value

returns a paged collection of all assets that match the query. See Asset queries for details.

POST /customers/2/allImages
{
"@type": "Collection",
"member": [
{"id": "2/36/PHOTO.2.22.36.2.tif"},
{"id": "2/17/my-image.jpg"}
]
}

This request, POSTed to the endpoint, returns a hydra:Collection with two members, the full resource information for the images with the given id values. Note that the requested images are for the same customer (if they are not the request will be rejected) but different spaces.

A link to a paged Collection of all Origin Strategy resources associated with your customer.

See Origin Strategy.

domainrangereadonlywriteonly
vocab:Customer🔗 hydra:Collection (of vocab:CustomerOriginStrategy)TrueFalse

/customers/{customer}/originStrategies

MethodLabelExpectsReturnsStatus
GETList all your origin strategies-A paged hydra:Collection of vocab:CustomerOriginStrategy200 OK
POSTAdd a new parameterised vocab:CustomerOriginStrategy instance. The platform will assign the identifier (a GUID) to the new CustomerOriginStrategy if you do not supply an id property in the request body.-vocab:CustomerOriginStrategy201 Created
POST /customers/2/originStrategies
{
"regex": "*",
"strategy": "https://api.dlcs.example/originStrategies/basic-http-authentication",
"credentials": "{ \"user\": \"uuu\", \"password\": \"ppp\" }",
"optimised": false,
"order": 1
}
field
regexREQUIRED
strategyREQUIRED
credentialsREQUIRED or OPTIONAL depending on strategy
optimisedOPTIONAL
orderOPTIONAL

See also the PUT and DELETE operations on CustomerOriginStrategy itself - you can use PUT to create without a GUID identifier.

A link to a paged Collection of further Collections of Delivery Channel Policies resources associated with your customer. Delivery Channel Policies control what the platform does with the asset you supply - e.g., make an image service (the iiif-img channel), make thumbss at your desired sizes (the thumbs delivery channel), transcode video (the iiif-av delivery channel) or simply serve up the file (the file delivery channel). Assets can have multiple channels, and different assets can have different policies for the same channel. See Delivery Channels.

When you add an asset to the platform, you specify the combination of delivery channel AND the policy it should use for that channel - or your asset inherits configured defaults from its space or customer (this collection).

This property on the Customer resource is a rare example of nested Collections - for organisational purposes.

domainrangereadonlywriteonly
vocab:Customer🔗 hydra:Collection (of hydra:Collection)TrueFalse

/customers/{customer}/deliveryChannelPolicies

MethodLabelExpectsReturnsStatus
GETRetrieve the available collections of policies per channel-A hydra:Collection of hydra:Collection200 OK

You can’t POST anything to the collection at /customers/{customer}/deliveryChannelPolicies - you can’t make your own “folders” within it - the (currently) four collections are fixed. But you can post DeliveryChannelPolicy resources to these “folders” already there, for example:

/customers/{customer}/deliveryChannelPolicies/thumbs

MethodLabelExpectsReturnsStatus
GETRetrieve your configured Delivery Channel Policies for the thumbs channel-A hydra:Collection of vocab:DeliveryChannelPolicy200 OK
POSTAdd a Delivery Channel Policyvocab:DeliveryChannelPolicyvocab:DeliveryChannelPolicy201 Created

An example POST:

POST /customers/{customer}/deliveryChannelPolicies/thumbs
{
"name": "my-custom-thumbs",
"displayName": "Standard set of thumbs for use on our website",
"channel": "thumbs",
"policyData": "[ \"2048,\", \"1336,\", \"880,\", \"^!1024,1024\", \"^!400,400\", \"^,250\" ]"
}
field
nameREQUIRED in POST; the patform will not mint an identifier/path element for a delivery channel policy
displayNameOPTIONAL
channelREQUIRED and must match the parent path (e.g., “thumbs” for the above example)
policyDataREQUIRED or OPTIONAL depending on channel

You can also PUT new policies directly into these nested collections, as described in Delivery Channels.

A link to a paged Collection of default Delivery Channels. These are only used when you register an asset without supplying any delivery channels on the submitted asset resource. The platform uses the mediaType of the asset to match one of these. It looks in the defaultDeliveryChannels property of the asset’s Space first, and continues looking at this customer level if none match from those in the space.

domainrangereadonlywriteonly
vocab:Customer🔗 hydra:Collection (of vocab:DeliveryChannel)TrueFalse

Unlike delivery channels on assets, any delivery channels listed here MUST have the mediaType property, which is used by the platform to match them to an asset. See Delivery Channels.

/customers/{customer}/defaultDeliveryChannels

MethodLabelExpectsReturnsStatus
GETList all your default Delivery Channels-A paged hydra:Collection of vocab:DeliveryChannel200 OK
POSTAdd a new default Delivery Channel. The body must include the mediaType property. The platform will create a GUID for the last path element, which you can use on PUT and DELETE operations.-vocab:DeliveryChannel201 Created
POST /customers/2/defaultDeliveryChannels
{
"channel": "iiif-img",
"policy": "https://api.dlcs.example/customers/{customer}/deliveryChannelPolicies/iiif-av/default-video",
"mediaType": "application/mp4"
}
field
channelREQUIRED
policyREQUIRED
mediaTypeREQUIRED

See also the PUT and DELETE operations on DeliveryChannel.

NB this is not a collection of collections like deliveryChannelPolicies.

Collection of all the Named Queries you have configured (plus those provided ‘out of the box’). See the Named Query topic for further information.

domainrangereadonlywriteonly
vocab:Customer🔗 hydra:Collection (of vocab:NamedQuery)TrueFalse

/customers/{customer}/namedQueries

MethodLabelExpectsReturnsStatus
GETRetrieves all Named Queries-A paged hydra:Collection of vocab:NamedQuery200 OK
POSTCreates a new Named Query. The platform will create a GUID for the last path element, which you can use on PUT and DELETE operations.vocab:NamedQueryvocab:NamedQuery201 Created
POST /customers/2/namedQueries
{
"name": "manifest-from-space",
"template": "manifest=s1&sequence=0&canvas=n1&s1=p1"
}
field
nameREQUIRED
templateREQUIRED

The syntax for the named query template is covered in Named Query.

When your customer is created, a few sample named queries are included for you to use.

The Customer’s view on the platform ingest queue. As well as allowing you to query the status of batches you have registered, you can POST new batches to the queue.

domainrangereadonlywriteonly
vocab:Customervocab:QueueTrueFalse

See Queues for details.

/customers/{customer}/queue

MethodLabelExpectsReturnsStatus
GETReturns the queue resource-vocab:Queue200 OK
POSTSubmit a collection of assets and get a batch back.🔗 hydra:Collection (of vocab:NamedImageQuery)vocab:Batch201 Job has been accepted - Batch created and returned

Collection of user accounts that can log into the portal. Use this to grant access to others in your organisation.

domainrangereadonlywriteonly
vocab:Customer🔗 hydra:Collection (of vocab:PortalUser)TrueFalse

/customers/{customer}/portalUsers

MethodLabelExpectsReturnsStatus
GETRetrieves all portal users-🔗 hydra:Collection (of vocab:PortalUser)200 OK
POSTCreates a new portal uservocab:PortalUservocab:PortalUser201 Created
POST /customers/2/portalUsers
{
"email": "user@example.com",
"password": "plaintext-password"
}

Returns information about storage usage for the customer across all spaces. See the StoragePolicy topic for more information.

domainrangereadonlywriteonly
vocab:Customervocab:CustomerStorageTrueFalse

/customers/{customer}/storage

MethodLabelExpectsReturnsStatus
GETReturns the customer storage resource-vocab:CustomerStorage200 OK

Api keys allocated to this customer. The accompanying secret is only available at creation time. To obtain a key and a secret, make an empty POST to this collection with administrator privileges and the returned Key object will include the generated secret.

domainrangereadonlywriteonly
vocab:Customerhydra:CollectionTrueFalse

/customers/{customer}/keys

MethodLabelExpectsReturnsStatus
GETReturns current set of API keys (secret omitted)-🔗 hydra:Collection (of vocab:Key)200 OK
POSTCreate a new key-vocab:Key (with secret, once)200 OK

The returned collection has vocab:key members like this:

"member": [
{
"@id": "https://api.dlcs.example/customers/2/keys/9b060235-71d2-49a1-ac54-e4a1b36e79ff",
"@type": "vocab:Key",
"key": "9b060235-71d2-49a1-ac54-e4a1b36e79ff"
},
{
"@id": "https://api.dlcs.example/customers/2/keys/93c93bf4-b7ea-4859-91e5-26a8f6e29c86",
"@type": "vocab:Key",
"key": "93c93bf4-b7ea-4859-91e5-26a8f6e29c86"
}
]

The secret property is only returned once, when creating a new key with an empty POST to the collection:

{
"@context": "https://dlcs.github.io/vocab/context/future.json",
"@id": "https://api.dlcs.example/customers/2/keys/22d85624-31b4-4e00-bd97-8e7d126b1d9f",
"@type": "vocab:Key",
"key": "22d85624-31b4-4e00-bd97-8e7d126b1d9f",
"secret": "................................................."
}

It’s up to you to keep the secret safe!

An individual key can be deleted with an HTTP DELETE to its URI:

DELETE https://api.dlcs.example/customers/2/keys/93c93bf4-b7ea-4859-91e5-26a8f6e29c86

A collection of custom HTTP headers. Adding a Custom Header resource to this collection will cause it to be set on every HTTP response for info.json, image tiles and other asset delivery responses.

See Custom Headers.

domainrangereadonlywriteonly
vocab:Customerhydra:CollectionTrueFalse

/customers/{customer}/customHeaders

MethodLabelExpectsReturnsStatus
GETReturns current set of custom headers-🔗 hydra:Collection (of vocab:CustomHeader)200 OK
POSTAdd a new custom header. The platform will assign the identifier (a GUID) to the custom header-vocab:CustomHeader201 Created

At the very least the request payload should provide a key and value. Without any further properties, ALL your public-facing responses will get this header. You can restrict to assets in a particular space, or assets with a particular role.

POST /customers/{customer}/customHeaders
{
"key": "Cache-Control",
"value": "public, s-maxage=2419200, max-age=2419200",
"space": 1
}

The above is so common that you will already have this custom header when your Customer is created.

field
keyREQUIRED
valueREQUIRED
spaceOPTIONAL
roleOPTIONAL

See also the PUT and DELETE operations on Custom Header itself.