Preserve a digital object for the first time
Use case: preserve a digital object — a set of files that includes a METS file describing the object. The object does not yet exist in the repository; this will be version v1.
This is the workflow for consumers who manage and supply their own METS file. You use the platform for versioned object storage rather than for generating or managing the content of your objects, so none of the METS editing or pipeline operations come into it. If you would rather the platform wrote the METS for you, see Managed METS deposit instead.
-
Make a Container to put it in, if you need one
Section titled “Make a Container to put it in, if you need one”You can only create repository structure outside preserved objects; Containers within an object come from Import Jobs. So if the parent Container does not exist yet, make it first:
GET /repository/library/c20-printed-books=> 404 Not FoundPUT /repository/library/c20-printed-books{"type": "Container","name": "20th Century Printed Books"}=> 201 CreatedSee Repository for what you can and can’t do here.
-
Create a Deposit
Section titled “Create a Deposit”POST /deposits{"type": "Deposit","archivalGroup": "https://preservation-api.example/repository/library/c20-printed-books/my-book","archivalGroupName": "My Book","submissionText": "A note from me for anyone interested"}Minimally an empty object is OK, though unusual — you can decide where the object goes later, and patch it in. But you do have to set
archivalGroupbefore you can ask for an Import Job, so setting it now saves a step.Leave
templateunset (or sendNone): you are supplying the METS, and a template would have the platform write one.This returns
201 Createdwith the new Deposit as the body. The property that matters next isfiles:{"id": "https://preservation-api.example/deposits/szwettbzp4xw","type": "Deposit","archivalGroup": "https://preservation-api.example/repository/library/c20-printed-books/my-book","archivalGroupExists": false,"files": "s3://working-bucket/deposits/szwettbzp4xw/","status": "new","template": "None","active": true// ... the other Deposit properties} -
Upload the files
Section titled “Upload the files”The
filesproperty is where the content of the new object goes. You interact directly with the AWS API (or, for another kind of backing store, whatever copying mechanism it offers) — there is no endpoint to POST bytes to.With no template the layout is yours to choose; the platform preserves what the METS describes. The convention the rest of the platform uses — and the one an exported object will come back in — is an
objects/folder for the content and ametadata/folder for anything said about it, so following it will save you trouble later.The files must include a METS file in the root of the workspace that provides a SHA256 digest for each file, as PREMIS metadata attached to the file’s entry:
<premis:fixity><premis:messageDigestAlgorithm>SHA256</premis:messageDigestAlgorithm><premis:messageDigest>49ea24a3070c92a393289685ad9d3c3d71e5c23f0ac72e76e63aac658dc3ee59</premis:messageDigest></premis:fixity>You do not need to describe the METS file in its own METS: the platform adds it to the object itself, with a digest taken from storage.
-
Set anything you left out
Section titled “Set anything you left out”If the Deposit was created from an empty body, or you have changed your mind, patch
archivalGroup,archivalGroupNameorsubmissionText:PATCH /deposits/szwettbzp4xw{"archivalGroup": "https://preservation-api.example/repository/library/c20-printed-books/my-other-book","archivalGroupName": "My Other Book","submissionText": "I changed my mind about what this is called"} -
Create and execute an Import Job in a single operation
Section titled “Create and execute an Import Job in a single operation”This is the shortcut for when you don’t need to see or modify the Import Job and can rely on the API to generate it for you:
POST /deposits/szwettbzp4xw/importjobs{"id": "/deposits/szwettbzp4xw/importjobs/diff"}The returned object is an ImportJobResult at
201 Created:{"id": "https://preservation-api.example/deposits/szwettbzp4xw/importjobs/results/ge7n4ds2","type": "ImportJobResult","importJob": "https://preservation-api.example/deposits/szwettbzp4xw/importjobs/transient/638950821343621834","originalImportJob": "https://preservation-api.example/deposits/szwettbzp4xw/importjobs/diff","deposit": "https://preservation-api.example/deposits/szwettbzp4xw","archivalGroup": "https://preservation-api.example/repository/library/c20-printed-books/my-other-book","status": "waiting","dateBegun": null,"dateFinished": null,"sourceVersion": null,"newVersion": null,"errors": null,"containersAdded": [],"binariesAdded": []// ... the other result lists} -
Poll the result until it has finished
Section titled “Poll the result until it has finished”GET /deposits/szwettbzp4xw/importjobs/results/ge7n4ds2You can do this as little or often as you like — or even not at all. Over time you expect
statusto becomecompleted,newVersionto becomev1, andbinariesAddedand its neighbours to fill up.A
completedWithErrorsmeans nothing was preserved;errorssays why. The Deposit becomes inactive either way, and you can reactivate it to try again. -
Load the Archival Group
Section titled “Load the Archival Group”Whether it’s one you have just created or one that has existed for years, this is no different from browsing any other part of the repository:
GET /repository/library/c20-printed-books/my-other-book
Starting from an identifier instead
Section titled “Starting from an identifier instead”If the platform is integrated with an identity service that already knows where your object belongs, you can skip deciding on a path and a title. POST the identifier instead of a Deposit:
POST /deposits/from-identifier{ "schema": "catirn", "value": "1000001"}The Deposit comes back with archivalGroup and archivalGroupName already filled in — here, the API consulted an external service to learn that 1000001 should be preserved at .../library/c18-printed-books/a-10000001 and that its title is “A Treatise on Opticks”. From that point on the flow is exactly the same, without step 4. See Creating a Deposit from an identifier for the schemas.