Skip to content

A deposit whose METS the platform manages

Use case: you have files to preserve and no METS file, and you would like the platform to describe them — to identify their formats, scan them for viruses, and record all of that as the object’s metadata.

This is the other side of the fork from preserving your own METS. Here you create the Deposit from a template, which gives you a mets.xml the platform wrote and may therefore edit, and you drive it through the API rather than writing XML.

  1. Create a Deposit from the RootLevel template

    Section titled “Create a Deposit from the RootLevel template”
    POST /deposits
    {
    "type": "Deposit",
    "template": "RootLevel",
    "archivalGroup": "https://preservation-api.example/repository/library/born-digital/hard-drive-14",
    "archivalGroupName": "Hard drive 14",
    "submissionText": "Accession 2025/112"
    }

    The workspace is scaffolded for you:

    /
    objects/
    metadata/
    ad-hoc/
    mets.xml

    objects/ is for the files you want to preserve; everything must be in or below it. metadata/ is where tool outputs go, and metadata/ad-hoc/ is for metadata files that belong to the object but are not the output of any tool. All three are recorded in the new METS file as well as in S3.

  2. Into objects/, with the S3 API, exactly as in the other workflows. Arrange them in whatever folder structure the material calls for.

    You don’t need checksums this time: the pipeline will produce them.

  3. POST /deposits/e56fb7yg/pipeline
    HTTP/1.1 204 No Content

    This queues a job that runs the platform’s characterisation tools against the Deposit’s objects/ folder — format identification, virus scanning, and the rest — and writes what they find back into the Deposit’s metadata/ folder.

    It is refused with 409 Conflict if somebody else holds a lock on the Deposit.

  4. GET /deposits/e56fb7yg/pipelinerunjobs

    A list of results, newest run last. Each carries a status, which moves through waitingprocessingmetadataCreatedcompleted (or completedWithErrors). metadataCreated means the tools have run but their output has not yet been uploaded back into the Deposit; wait for completed.

    The individual job is at GET /deposits/e56fb7yg/pipelinerunjobs/<jobId>.

  5. GET /deposits/e56fb7yg/filesystem?refresh=true

    The file system view shows not just the layout but the metadata collected for each file from the tool outputs: digests, PRONOM format identifications, virus scan results.

    If you ran the pipeline in the previous step, the METS is already populated: once the tools finish, the run adds every file under objects/ to the METS, and adds its own output files as it uploads them. The next step is then a top-up rather than a necessity.

    If the tool output arrived some other way — analysis run outside the platform and uploaded with the files — nothing has pushed it into the XML, and the next step is what does it. Synchronising a Deposit with its METS is a separate, explicit step precisely because the platform may not have been the one that looked at the files, and because not every file you analysed necessarily belongs in the preserved object.

  6. POST /deposits/e56fb7yg/mets
    If-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d"
    [
    "objects/image_001.tif",
    "objects/image_002.tif",
    "objects/docs/notes.txt",
    "metadata/brunnhilde/siegfried.csv",
    "metadata/brunnhilde/logs/viruscheck-log.txt"
    ]

    A list of paths relative to the root of the Deposit. Parent folders are created for you; folders are not expanded, so list every file you want. The If-Match is the Deposit’s metsETagfetch the Deposit again to get it. It is null in the response to creating one, and a pipeline run will have changed it since, so an ETag held from earlier in this walk-through is stale and will be refused with a 409.

    The platform adds each file to the METS with all the metadata it has collected for it — which is why this step comes after the pipeline and not before. See Editing the METS for the rules and the response.

    You can call it again at any time; entries already present are updated rather than duplicated.

  7. Remove anything that shouldn’t be preserved

    Section titled “Remove anything that shouldn’t be preserved”
    POST /deposits/e56fb7yg/mets/delete
    If-Match: "…"
    {
    "deleteFromMets": true,
    "deleteFromDepositFiles": true,
    "items": [
    { "path": "objects/thumbs.db", "isDir": false }
    ]
    }

    This takes the file out of the workspace and out of the METS together. A file you simply don’t add to the METS is not preserved either, so deletion is only for things you want gone from the Deposit as well.

  8. GET /deposits/e56fb7yg/combined

    The combined view is the Deposit’s file tree and the METS structure merged, which is exactly what the diff Import Job is computed from. Anything sitting in the Deposit but not the METS will stop the diff.

    That endpoint is a debugging aid, though, and hidden from the API description for a reason: the structure holds references in both directions, so the JSON grows alarmingly with the size of the deposit. In normal use compare GET /deposits/{id}/filesystem with GET /deposits/{id}/parsed-mets, or simply ask for the diff and read its 422.

  9. POST /deposits/e56fb7yg/importjobs
    {
    "id": "/deposits/e56fb7yg/importjobs/diff"
    }

    And poll the ImportJobResult until it reaches completed. The object is preserved as v1, with its characterisation metadata inside its METS, where a future reader of the OCFL object can find it without the platform.

To add more files later, upload them, run the pipeline again, and POST the same paths to .../mets once more: the entries are updated with whatever the tools found the second time. Do all of that before the Import Job — once a Deposit’s job has run successfully, the Deposit is finished, and a further change means a new Deposit against the now-existing Archival Group, as in Update without export.