Integration API

Reference: sync manifest

GET /sync – everything a key can see in one list, to find what was deleted.

GET /sync

Scope read. Every document and category the key can see, with only the fields needed to compare. Use it to find what has gone: deleted, archived out of the released view, or out of the acting person's reach.

complete
boolean
false if there are more than 50,000 documents and the list was cut off. Then do not delete anything based on it.
documents[].checksum
string | null
SHA-256 of the current version. If yours differs, download the file again.
documents[].categoryIds
uuid[]
Where it is filed, among the categories the key can see. This also catches a re-filing made in the CMS.

Request

curl https://ddm.example.com/api/ext/v1/sync \
  -H "Authorization: Bearer $DDM_API_KEY"

Response · 200 OK

{
  "generatedAt": "2026-10-27T20:01:47.990Z",
  "complete": true,
  "documents": [
    {
      "id": "dc8594e0-0ead-4049-aaee-2ef899bcf76f",
      "externalRef": "PIM-4711",
      "sourceId": "5d02b7aa-5175-42e9-9277-aa19063833f2",
      "status": "draft",
      "currentVersionId": "1730e7bb-2f98-4761-aa9b-964c521351b3",
      "checksum": "0bcb7c3b4886f699a985563d7bc9476bf75b4af35a57ff959f46c37e386cf54f",
      "categoryIds": [
        "078a554f-19a2-4285-b854-8546de01f815"
      ],
      "updatedAt": "2026-10-27T20:01:47.284Z"
    }
  ],
  "categories": [
    {
      "id": "7a7afae0-f77b-478b-975d-d29eace15d51",
      "parentId": null,
      "externalRef": "CAT-10",
      "updatedAt": "2026-10-27T20:01:46.086Z"
    },
    {
      "id": "078a554f-19a2-4285-b854-8546de01f815",
      "parentId": "7a7afae0-f77b-478b-975d-d29eace15d51",
      "externalRef": "CAT-11",
      "updatedAt": "2026-10-27T20:01:46.138Z"
    },
    {
      "id": "45dc485e-d982-466a-8ab6-e8ac328b800f",
      "parentId": "7a7afae0-f77b-478b-975d-d29eace15d51",
      "externalRef": null,
      "updatedAt": "2026-10-27T20:01:46.200Z"
    }
  ]
}

Example: finding deleted documents

Keep the manifest of each run. On the next run, fetch a new one and compare: every id that was in the old one and is missing from the new one is gone for this key. The document may have been deleted, archived out of the released view, or moved where the key's person cannot see it.

# The manifest of the last run is in manifest-previous.json.
curl -s https://ddm.example.com/api/ext/v1/sync \
  -H "Authorization: Bearer $DDM_API_KEY" > manifest.json

# Cut off above 50,000 documents? Then compare nothing.
if [ "$(jq .complete manifest.json)" != "true" ]; then
  echo "Manifest incomplete – not deleting anything" >&2; exit 1
fi

# The ids that were there last time and are not any more.
jq -r '.documents[].id' manifest-previous.json | sort > previous.txt
jq -r '.documents[].id' manifest.json | sort > current.txt
comm -23 previous.txt current.txt > gone.txt

while read -r id; do
  echo "gone: $id"   # remove it from your system here
done < gone.txt

mv manifest.json manifest-previous.json

What "gone" means is the same in all three cases: remove the document from your system, or hide it there. If you need to know why it is gone, ask GET /documents/{id} with a key that sees everything. 404 means it was deleted; otherwise its status and categoryIds tell you what changed.

Only compare a manifest whose complete is true. And treat a manifest that is suddenly empty or much smaller with suspicion – a revoked permission or a changed acting person makes everything "disappear" at once. A sensible guard: stop and alert someone if more than, say, 10 % of documents would be deleted in one run.

Change feed or manifest?

QuestionUse
What is new or changed since my last run?GET /documents?updatedSince=… – small, fast, paged
What is gone?GET /sync – complete, but larger
Has anything been re-filed or re-tagged in the CMS?GET /sync for the filing, GET /documents/{id} for the tags

A good rhythm: the change feed every few minutes, and the manifest once an hour or once a night.