Integrating a Custom DAM System with Specify

:gear: This guide is for technical and IT users who want to integrate an existing or developing Digital Asset Management (DAM) system with Specify.

If your institution uses a custom Digital Asset Management (DAM) system and you want Specify to connect to it directly, you can do this by having your DAM act like the default Web Asset Server (WAS).

Some institutions choose to manage a drive of high-quality originals detached from the Specify instance, while others seek to use the same DAM between the collections management system and elsewhere in their institution.

By either building an adapter in your DAM or placing a proxy layer between Specify and the DAM, Specify can use your external system to store, retrieve, and delete attachments.

[!caution] Support Warning
Support for the integration, development, or maintenance of third-party Digital Asset Management (DAM) systems is not included in the scope of the support services offered to members.

Specify Cloud users can contact support@specifysoftware.org directly to configure their instance to use a custom DAM or WAS alternative.

For assistance with integration, please contact membership@specifysoftware.org for more information about consulting costs.

Before you begin, please review:


Integration Approaches

If it is not viable to use the WAS provided by the SCC, you have three main options for bridging your custom DAM to Specify:

  1. Adapter: Implement the required asset-server endpoints directly within your DAM application so Specify can communicate with it natively.
  2. Proxy / Translator: Keep your DAM API exactly as it is, but stand up a small proxy service that exposes the asset-server endpoints to Specify and translates those requests to your DAM.
  3. Hybrid: Serve heavy asset operations (like downloads and thumbnails) directly from the DAM, but expose a lightweight compatibility layer solely for token signing and API discovery.

Before beginning any of these approaches, we recommend thoroughly reviewing the WAS repository to get a clear idea of how the asset server works:


Implementation

To integrate successfully, your DAM (or proxy) must implement the following endpoints with the expected semantics. Each endpoint must accept the token authentication used by the WAS and return compatible responses.

1. Discovery (/web_asset_store.xml)

Specify requests an XML document to discover the endpoint URLs. See the template in views/web_asset_store.xml.

<?xml version="1.0" encoding="UTF-8"?>
<urls>
  <url type="read"><![CDATA[http://{{host}}/fileget]]></url>
  <url type="write"><![CDATA[http://{{host}}/fileupload]]></url>
  <url type="delete"><![CDATA[http://{{host}}/filedelete]]></url>
  <url type="getmetadata"><![CDATA[http://{{host}}/getmetadata]]></url>
  <url type="testkey">http://{{host}}/testkey</url>
</urls>

2. Uploads (/fileupload)

Implementation reference: server.py

  • Accepts: Multipart uploads containing the file payload, plus form fields store, type, and coll.
  • Auth: Requires token (see below).
  • Returns: Plain text Ok. on success.

3. Downloads (/fileget)

Implementation reference: server.py

  • Accepts: Query params filename, coll, type (for thumbnails, type=T and scale are used), plus token when required.
  • Returns: The file bytes with the correct Content-Type and optional Content-Disposition.

4. Deletions (/filedelete)

Implementation reference: server.py

  • Accepts: POST form fields filename and coll.
  • Returns: Plain text Ok. after deleting the original and any derived thumbnails.

5. Metadata (/getmetadata)

Implementation reference: server.py

  • Accepts: Query params filename, coll, and optional dt=date.
  • Returns: JSON containing EXIF fields, or plain text date when dt=date is provided.

6. Storage Layout & Thumbnails

Implementation reference: server.py
Organize originals and thumbnails in predictable paths, for example:

  • /data/originals/{store}/{filename}
  • /data/thumbnails/{store}/{filename} (thumbnails are cached with a _<size> suffix)

Thumbnails should be generated on demand, cached, and invalidated upon deletion. If your DAM already has a thumbnail API, simply expose a compatible path or translate the requests in your proxy. See this guide to learn more about how thumbnails are generated on the default WAS.


Token Signing & Authentication

Implementation reference: server.py

Specify secures WAS requests by generating time-limited signed tokens. Your custom integration needs to correctly re-compute and verify these tokens.

  • Canonical String: "<timestamp><filename>" (string concatenation).
  • Algorithm: Sign with HMAC-MD5 using your shared attachment key, then encode as hex. The token value is "<hexdigest>:<timestamp>".
  • Request Format: Specify sends the token as a token query or form field; there is no separate ts parameter.
  • Verification: Recompute the HMAC on your end, compare using a constant-time check, and ensure the timestamp falls within your allowed window (e.g., abs(now - ts) <= 150s).

Configuration

To connect Specify to your DAM:

  1. Point Specify’s asset configuration to the DAM base URL (or to the proxy that handles Specify attachments).
    ASSET_SERVER_URL=http://host.docker.internal/web_asset_store.xml
    # Make sure to set the `ASSET_SERVER_KEY` to a unique value
    ASSET_SERVER_KEY=your_asset_server_access_key
    
  2. Set the shared attachment key in Specify to match the secret used by your DAM/token verifier.
  3. Ensure your web server routes the specific asset paths to your DAM or proxy.

Testing Checklist

Once your endpoints are live, walk through this checklist to confirm the integration:

  1. GET /web_asset_store.xml — Discovery returns the correct XML.
  2. GET /testkey?token=... — Verify the test key. Implementation reference for test key: server.py
  3. POST /fileupload (with token) — File is stored and returns Ok..
  4. GET /fileget (with token when required) — Returns correct file bytes and headers.
  5. GET /getmetadata — Metadata (e.g., EXIF capture date) is successfully retrieved for the uploaded file.
  6. POST /filedelete — Returns Ok., removing both the original and its thumbnails. Test with a follow-up GET /fileget to confirm it returns 404 Not Found.

If all is working as expected, your DAM has successfully replaced the default WAS for Specify attachments!