Digital rights management and secured fulfilment, from DMI Systems hello@dmi.systems Operator login
Digital Media ReserveAn imprint of DMI Systems

For developers

Web services integration

Your site keeps the catalogue, the cart and the customer. DMR issues the licence and the link. Three operations connect the two — over REST for new builds, over SOAP for the retailers already running on it.

How the integration is shaped

Publishers upload their masters to the Digital Media Reserve repository. Publishers and retailers then integrate with the reserve in order to sell or lend those files from their own website. Whichever transport you use, the reserve never sees your customer and you never see the encryption.

New integrations use the REST API — JSON over HTTPS, bearer-token authentication, the same three operations. SOAP remains supported for retailers already built on it; it is not deprecated and it is not going anywhere.

What your site needs

A storefront that can call an API
Any language, any framework. For REST, anything that can make an authenticated HTTPS request and read JSON.
Somewhere server-side to keep credentials
Your token, or your CommerceID, RetailerID and RetailerKey. Never in client-side code.
A static IP
For SOAP, your site must be bound to a static address, which we allow-list against your retailer account. REST accounts can be IP-restricted on request.
Nothing else
No platform migration, no change of payment gateway, and no rebuild of your catalogue pages.

Onboarding

Getting a retail site connected

  1. Apply for a retailer account

    On approval we issue your credentials — a bearer token for REST, or CommerceID, RetailerID and RetailerKey for SOAP.

  2. Pull the catalogue

    Export the metadata for available titles as XML, or point an ONIX feed at the reserve and let it stay in step by itself.

  3. Build your product pages

    Import that metadata so customers can find and buy from your own catalogue pages, in your own design.

  4. Store credentials server-side

    Credentials sign every call and never belong in client-side code.

  5. Check availability in your add-to-cart flow

    Confirm the item is available in the requested format before you ask anyone to pay.

  6. Create the transaction after payment succeeds

    Exchange your transaction ID for the download link, and present that link to your customer.

Reference

The three operations

The same three whichever transport you use. Each card shows the REST path first and the SOAP service name beneath it.

Availability

Given an item and a format, tells you whether it is available for sale or loan before you ask anyone to pay.
POST /v1/availability
CheckAvailability

Transaction

Given your own transaction ID, returns the protected download link for the fulfilled file.
POST /v1/transactions
NewTransaction

Re-issue

Against the same transaction ID, re-issues the link — for a customer who lost the file or changed device.
POST /v1/transactions/{{id}}/link
RegenerateDownloadLink

REST — check, then fulfil

Request
POST /v1/transactions
Authorization: Bearer <retailer token>
Content-Type: application/json

{
  "transaction_id": "your-order-4471",
  "item_id":        "dmr:9788195xxxxxx",
  "format":         "epub",       // epub | pdfa | video
  "protection":     "acs",        // acs | social
  "recipient": {
    "name":  "A. Reader",        // used by social DRM
    "email": "reader@example.com"
  }
}
Response
200 OK
{
  "transaction_id": "your-order-4471",
  "download_url":   "https://…/fulfil/9f2c…",
  "expires_at":     "2026-09-13T11:04:00Z",
  "protection":     "acs"
}

409 Conflict
{
  "error": {
    "code":    "DUPLICATE_TRANSID",
    "message": "Duplicate transaction ID."
  }
}

Error codes are shared with the SOAP services, so a retailer moving from one to the other keeps their existing error handling.

SOAP — the original services

Response — NewTransaction
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope>
 <SOAP-ENV:Body>
  <NewTransactionResponse>
   <Books><Book>
    <DownloadLink>Download link for BookID</DownloadLink>
   </Book></Books>
  </NewTransactionResponse>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Signing the request — PHP
/* Hash your retailer credentials before every call. */
$stringpass = md5($commerceid) . $retailerid . $bookid . $format . $transid;
$password   = hash_hmac("sha1", $stringpass, $retailerkey);

$client->addHeader(array('Username', md5($commerceid), $_NS));
$client->addHeader(array('Password', $password, $_NS));

$result = $client->call('NewTransaction', array(
  'RetailerID' => $retailerid,
  'TransID'    => $transid,
  'BookID'     => $bookid,
  'Format'     => $format
), $options);

Endpoint /webservices/retailers/. Reference implementation uses PEAR-SOAP 0.12.0; any SOAP client that can set envelope headers will do.

About this reference

The REST paths and payloads shown above illustrate the shape of the API so you can judge the integration effort before you commit to it. The authoritative reference — with the full schema, rate limits and sandbox credentials — is issued with your retailer account. The SOAP services are documented exactly as they run today.

Catalogue

ONIX catalogue sync

Nobody should be re-typing a subtitle into three systems. Send us ONIX for Books and your catalogue in the reserve keeps itself current — titles, contributors, subjects, prices, rights territories and availability.

Publishers who already generate ONIX for their distributors can point the same feed at the reserve. Publishers who do not can have it built — OnixMaster is the group's own ONIX application, and it comes with an e-commerce web-store that the reserve can fulfil protected files behind.

Scheduled or on-demand
Drop a feed on a schedule, or push an update when a title changes.
New titles appear without re-keying
A record added to your feed becomes a catalogue entry in the reserve.
Descriptive data carried through
Title, contributors, subjects, product form and prices come across as they stand in your ONIX.
Retailers pull it back out
Your integrated retailers export catalogue metadata as XML and build their product pages from it.

Parameters

These are the SOAP parameters. All six are mandatory on every call that uses them. TransIDtransaction_id in REST — is yours to choose and yours to keep: it is the only handle you have for regenerating a link later.

Web service parameters
NameDescription
UsernameIdentifies the retailer. Pass the MD5 hash of the CommerceID issued by Digital Media Reserve.
PasswordA SHA-1 HMAC used to validate the integrity of the calling retailer.
RetailerIDThe unique retailer ID assigned to your account.
TransIDYour own unique transaction ID. Used to regenerate a download link in future.
BookIDThe identifier Digital Media Reserve holds for each eBook.
FormatEPUB or PDF/A.

Error codes

Shared between both transports. In SOAP they arrive inside the envelope as a code and a message; in REST as an error object with the same code. Map them once and your support desk never has to read XML.

Error codes returned by the web services
CodeMeaningWhat to do
INVALID_SOAP_REQUESTInvalid SOAP request, got nothing.Check the endpoint and that a body was sent.
INVALID_SOAP_MESSAGEInvalid SOAP message.Validate the envelope against the samples above.
INVALID_HEADERA header parameter is blank.Confirm Username and Password are both set.
MISSING_PARAMETERThe request is missing a service parameter.All listed parameters are mandatory.
INVALID_USERNAMEInvalid input parameter: Username.Username must be the MD5 of your CommerceID.
INVALID_PASSWORDInvalid input parameter: Password.Re-check the HMAC string order and your retailer key.
ACNT_NOT_APPROVEDAccount approval is pending.Contact your DMR account manager.
ACNT_BLOCKEDThe account has been blocked.Contact accounts@dmi.systems.
RETAIL_ACNT_NOT_APPROVEDThe retail account is pending.Approval is per retailer, not per organisation.
RETAIL_ACNT_BLOCKEDThe retail account has been blocked.Contact accounts@dmi.systems.
INVALID_RETAILER_IDInvalid retailer ID.Check the RetailerID against the credentials issued to you.
DUPLICATE_TRANSIDDuplicate transaction ID.Use RegenerateDownloadLink instead of NewTransaction.
NOT_AVAILABLE_FOR_PURCHASEThe eBook is not available for purchase.Call CheckAvailability before taking payment.
ERROR_IN_LINK_GENERATIONError in link generation.Retry; if it persists, raise it with tech support.
TRANSID_NOT_EXISTSThe transaction ID does not exist.Only transactions created via NewTransaction can be regenerated.
INTERNAL_ERRORThe system is unable to process your request.Retry after a short interval.

Video integration

The video reserve uses a token-based REST flow rather than SOAP: your backend requests a one-time playback token (OTP) for a given video and viewer, and your page or app hands that token to the player. Watermark text, device policy and geography rules are set per token. Full video API notes are issued with your account.

Want the full manual?

The complete Retailer DRM Web Services manual — syntax, request and response samples, PHP reference code and the error table — is issued under NDA with your retailer account.