REST interface
With the REST interface system type, DDM fetches documents from a system that offers them through an HTTP interface – a DMS, a PIM, a shop, your own application. Unlike with SharePoint or FTP, DDM does not know how this interface is built. You describe it in a request chain: which addresses DDM calls, where in the response the list of documents is and what each value means.
That sounds more technical than the other sources – and it is. Expect to need somebody who knows the interface and has its documentation to hand.
What the interface must be able to do
DDM needs two things from it:
- A list of the documents as JSON (or XML) – with at least a name and an address where the file is.
- The file itself at this address, retrievable with a simple
GET.
Authentication is with one fixed header, e.g. an API token. A sign-in that first fetches a token can be modelled as a step of its own – see Example 3.
1. Add the source
Under Settings › External sources, add a source with New source, give it a name and choose REST interface as the System type.
| Field | What to enter |
|---|---|
| Base URL | The interface's common address, e.g. https://dms.company.com/api/v1. The steps' paths are appended to it |
| Authentication (header) | One header in the format Name: Value, e.g. Authorization: Bearer eyJhbGc… or X-API-Key: 7f3a…. For Basic Auth: Authorization: Basic and user:password in Base64. Stored encrypted, never shown again |
DDM sends this header only to the base URL – more precisely: to addresses with the same protocol, host and port. If a step calls another address or a file is on another server, the header is not sent there.
Click Test connection. DDM calls the base URL with GET and the header.
| Message | What to do |
|---|---|
| The interface answers (HTTP …). | The address is reachable. Even a 404 or 405 counts as „answers" here – many interfaces have nothing at the base URL itself. Whether the actual calls work is only shown by Test chain. |
| The interface rejected the credentials — check the authentication header. | Response 401 or 403 – the header is wrong or the token has expired. |
| The address redirects to … — please enter the target URL directly. | DDM does not follow redirects. Enter the address named as the base URL – often only https:// or a / at the end is missing. |
| This address may not be fetched (…). | The address is blocked – e.g. not http/https, or with a hosted DDM an address on a private network. |
| The address does not answer — check the URL, the port and the firewall. | The server cannot be reached. |
| The stored authentication can no longer be decrypted — please enter it again. | Enter the header again. |
2. Understanding the request chain
Under Request chain & field mapping, add one or more steps with + Step. Each step is one call to the interface. The steps run one after another:
- A step can iterate over a list in its response – for each entry, the next step runs once.
- A step can hand values on to the following ones as variables, e.g. a folder's ID.
- A field mapping says which value of the response is which detail of a document: name, file URL, category …
At the end, every entry of the last step that returned entries becomes a document – provided it has a name and a file URL.
A step
| Field | Meaning |
|---|---|
| Name | For you, e.g. „List documents" |
| Call | The method – GET, POST, PUT or DELETE – and the Path: relative to the base URL (documents) or a full address (https://…) – see Path and base URL |
| Headers | Additional headers for this step, one per line, e.g. Accept: application/json or X-Tenant: 42. They are always sent, to other servers too, and take precedence over the source's |
| Body | Only with POST and PUT: the content of the request, e.g. JSON. DDM sets the matching Content-Type itself – application/json for JSON, text/xml for XML –, unless the step names its own under Headers |
| Iterate over list | Where in the response the list is, e.g. items or data.documents. Empty = the whole response is one entry |
| Step active | The chain skips inactive steps |
With the arrows Move up / Move down you change the order.
Path and base URL
A step's path always goes below the base URL – whether it starts with / or not:
| Base URL | Path | DDM calls |
|---|---|---|
https://dms.company.com/api/v1 | documents or /documents | https://dms.company.com/api/v1/documents |
https://dms.company.com/api/v1 | ?page=2 | https://dms.company.com/api/v1?page=2 |
https://dms.company.com/api/v1 | (empty) or / | https://dms.company.com/api/v1 |
https://dms.company.com/api/v1 | https://cdn.company.com/x | https://cdn.company.com/x |
A document's File URL is different: it comes from your interface's response and is read like a link. If the interface returns /files/4711, DDM downloads https://dms.company.com/files/4711 – from the server root, not below /api/v1. That is what interfaces mean by such addresses.
Paths in the response
You give the place where a value is as a dotted path – not JSONPath, not XPath:
{
"data": {
"items": [
{ "id": 4711, "title": "Pricelist 2026", "file": { "url": "/files/4711" }, "tags": ["sales"] }
]
}
}
| Path | gives |
|---|---|
data.items | the list – this goes into Iterate over list |
title | Pricelist 2026 – relative to the single entry of the list |
file.url | /files/4711 |
tags.0 | sales – numbers access lists, starting at 0 |
| (empty) | the whole entry |
Paths in variables and field mappings always apply to one entry of the iterated list, not to the whole response.
Variables
Under Variables for later steps, set a Variable name and a JSON path with + Variable. In every later step you insert the value with {{name}} – in the Path, the Headers or the Body:
- Path:
folders/{{folderId}}/files - Header:
Authorization: Bearer {{token}} - Body:
{ "folder": "{{folderId}}" }
DDM inserts the values appropriately: URL-encoded in the path, in the body as JSON or XML text depending on the content. A variable name may only contain unaccented letters, digits, _, . and -. Under Incoming variables, each step shows which variables the earlier ones provide; one it uses is highlighted.
A path that consists only of a variable containing a full address – {{nextPage}} – is called unchanged.
Field mapping
Under Field mapping (JSON → attribute), map a path to a detail of the document with + Mapping:
| Attribute | Meaning | |
|---|---|---|
| Document name | Name of the document in DDM. The File filter goes by this name – with extension, e.g. Pricelist.pdf | required |
| File URL | Where the file is – relative to the base URL or complete. DDM downloads it with GET | required |
| External id | An ID that never changes in your system. DDM uses it to recognise the document at the next sync, even if it has been renamed | strongly recommended |
| Category path | The category, separated by /, e.g. Sales/Prices. Used according to the Category mapping in the import scope | |
| File type | The MIME type, e.g. application/pdf. Without it, whatever the server reports on download applies | |
| External group | A group from your system that is to get read access – see Group mapping | |
| Size (bytes), Modified at | Can be mapped but have no effect – DDM takes the file's actual size and detects changes by content |
Mappings in earlier steps apply to all entries that arise below them. So step 1 can, for example, provide the Category path from the folder name, and step 2 the name and file URL of the files in it.
Transformations
Every variable and every mapping can reshape the value before it is used:
| Transformation | Example |
|---|---|
| None | – |
| Lowercase / Uppercase | Sales → sales / SALES |
| Trim whitespace | Pricelist → Pricelist |
| Add prefix | 4711 with prefix dms- → dms-4711 |
| Add suffix | Pricelist with suffix .pdf → Pricelist.pdf – useful when the name has no extension |
| Replace | Search for \ Replace with / → Sales\Prices becomes Sales/Prices |
| Cut at separator | With separator ?: list.pdf?v=3 becomes list.pdf |
Beside each row, a preview shows what becomes of the first entry of the example response.
3. Test the chain
Click Test chain (or Test on a single step). DDM calls the steps without importing anything, and shows
- a status per step: ok, failed, skipped, unreachable, rejected, redirected or address blocked,
- under Example response, the step's response (the first 20,000 characters) – the basis for the previews,
- how many records resulted,
- in the Import scope under Structure preview, which path would go into which category,
- under Group mapping, the Groups found.
If a step fails (HTTP status 400 or above, or no response), the chain stops and the following steps are set to skipped. Beneath the failed step you see what came back – the status and the start of the response, e.g. the interface's error message. The Example response keeps the last successful response, so the previews are not lost. You can also paste the Example response by hand – e.g. from the interface's documentation – to prepare mappings before the connection is in place.
Once the chain works, sync once with Sync now in the Import scope and switch on Source active – see Overview.
Examples
Example 1: One list, one call
The interface returns under GET /documents:
{ "items": [ { "id": "4711", "title": "Pricelist.pdf", "url": "/files/4711", "folder": "Sales/Prices" } ] }
Step 1 – „Documents": GET documents, Iterate over list items.
| JSON path | Attribute |
|---|---|
title | Document name |
url | File URL |
id | External id |
folder | Category path |
Example 2: First the folders, then their files
GET /folders returns the folders, GET /folders/{id}/files the files of a folder.
Step 1 – „Folders": GET folders, Iterate over list items.
- Variable
id=id - Mapping
name→ Category path
Step 2 – „Files": GET folders/{{id}}/files, Iterate over list files.
- Mappings
title→ Document name,url→ File URL,fileId→ External id
Step 2 runs once per folder from step 1; each file gets the category path of its folder.
Example 3: Sign in first, then fetch
After POST /auth/token, the interface returns a short-lived token:
{ "access_token": "eyJhbGc…", "expires_in": 3600 }
Step 1 – „Sign in": POST auth/token, Body:
{ "client_id": "ddm", "client_secret": "…" }
- Variable
token=access_token - Iterate over list: empty
Step 2 – „Documents": GET documents, Headers Authorization: Bearer {{token}}, Iterate over list items, mappings as in example 1.
The downloaded files only get the header from Authentication (header) – not the token from step 1. If your server requires the token for the files too, the file URL itself must contain the access (such as a signed address), or the server must deliver files with the fixed header.
Group mapping
If your interface returns a group for each document – a department, a role, a customer group –, DDM can turn it into read access:
- In the chain, map the group's path to the External group attribute.
- Click Test chain. Under Group mapping, the Groups found appear.
- Click a group found (or + Mapping and type its name) and choose the DDM group that gets it.
On sync, every document gets read access for the DDM group mapped to its external group – in addition to the permissions of its category. Upper and lower case do not matter.
- Without a mapping, with No group or with Mapping active switched off, the import grants no rights for this group.
- Each document can have one external group.
- The import only grants rights, it never withdraws them. If a document's group changes in your system, the old DDM group keeps its read access – withdraw it on the document if needed.
Limits
| Limit | Value |
|---|---|
| Calls per sync, all steps together | 40 |
| Entries per step | 200 |
| Size of a response | 2 MB |
| Time per call | 30 seconds (20 when testing) |
| Time per file download | 60 seconds |
| Largest file | 25 MB |
DDM does not follow redirects (HTTP 3xx) – enter the target address directly.
There is no built-in paging (pagination): each step runs once per entry of the previous one, not „until nothing more comes". If your interface returns pages, request pages as large as possible (e.g. ?limit=200), or model a fixed number of pages as steps of their own – for instance with the variable {{nextPage}} from the first page's response as the path of the second step. If the maximum number of calls is reached, the test reports Stopped at the maximum number of calls …; split the source up then.