Skip to content

Storage API overview

The Storage API is the exclusive gateway to Fedora. Nothing else talks to Fedora - not the Preservation API’s clients, not the Preservation UI, not the iiif-builder. It is designed to sit on a private network, reachable only from the Preservation API and the Storage API Importer.

The Storage API hides the specifics of Fedora behind an interface that is only concerned with Containers, Binaries, Archival Groups and Import Jobs. It does not parse or understand the files it stores. A METS file is just another Binary to it; so is a TIFF, a spreadsheet or a disk image. The one place it acknowledges METS at all is POST /exportMetsOnly, which picks the file out by name so that it can be exported alone - it never reads it.

Its job is to:

  • present the repository as a navigable hierarchy of Containers, Archival Groups and Binaries;
  • execute Import Jobs - JSON documents describing files and folders somewhere outside Fedora that should be ingested into it - inside a Fedora transaction, however many files are involved, producing a new OCFL version;
  • export an Archival Group, at any version, to a location in S3;
  • stream the bytes of a preserved Binary, and report where each Binary actually lives in S3;
  • publish an activity stream of completed Import Jobs, which the Preservation API consumes to produce its own stream of Archival Groups.

It can store anything you can describe in an Import Job, as long as it has access to the origin locations of the binaries. It offers no modelling capability beyond the file system layout.

Where it differs from the Preservation API

Section titled “Where it differs from the Preservation API”

The resource types are the same, and so is most of the browsing. What is missing is everything to do with application concerns - METS, Deposits, tool outputs, IIIF. The table below says, for each concept introduced in the Preservation API section, what the Storage API does with it.

ConceptIn the Storage API
Container, Binary, ArchivalGroupThe same JSON shapes, with id and related URIs on the Storage API host. The Preservation API rewrites id, partOf, createdBy and lastModifiedBy to its own host when it passes a resource through - but not a Binary’s content, which stays as the Storage API minted it.
Browsing the repositoryThe same. GET /repository/..., the same view=lightweight and version parameters, the same HEAD behaviour and X-Preservation-Resource-Type header, the same PUT/DELETE for organisational Containers with ?purge=true.
view=mets and view=parsed-metsNot supported - the Storage API never parses a METS file. Any view other than lightweight is a 400.
Fetching file contentThis is where the /content/... path is actually served. See Activity and content.
DepositsDo not exist. The Storage API takes file locations, not workspaces.
METS and editing METSDo not exist.
Import JobsThe Storage API cannot generate one for you - there is no diff. It only executes jobs you construct and send. See Import.
Import Job ResultsThe same resource, polled in the same way, at a different path.
ExportsWork differently: you POST an Export resource naming an Archival Group and an S3 destination. See Export.
Activity StreamReports Import Jobs, not Archival Groups. Same IIIF Change Discovery shape, different subject.
Versions and the Storage MapThe same, at the same path. The Preservation API passes it straight through.
SearchA different thing entirely: a substring match over repository paths, read out of Fedora’s own database. See Activity and content.
Tool outputs and pipelinesDo not exist.
IIIFDoes not exist.
AgentsThe Storage API mints agent URIs on its own host and records them on resources, but does not serve them - there is no /agents route. Resolve agents through the Preservation API.

Throughout this documentation the Storage API is assumed to be at https://storage-api.example. The entry points are:

PathWhat it is
/repositoryThe root of the preserved repository. Identical in shape to the Preservation API’s.
/content/...The bytes of a preserved Binary.
/importSubmit an Import Job; poll its result under /import/results/....
/export, /exportMetsOnlyCopy an Archival Group, or just its METS file, out to S3.
/activity/importjobs/collectionThe activity stream of completed Import Jobs.
/ocfl/storagemap/...Where an Archival Group’s files are in OCFL, for any version.
/FedoraSearchSubstring search over repository paths.
/whoamiWho the API thinks you are.
/health, /fedora, /storagecheckConnectivity checks: the service itself, its Fedora connection, and its S3 access.

Authentication works exactly as it does for the Preservation API: a bearer JWT for the audience this instance validates, plus an X-Client-Identity header naming the caller. GET /whoami reports the identity the API resolved, with the same name, source, appId and depositBucket properties. See Authentication.

In practice the caller is the Preservation API, forwarding the original caller’s token where there is one, so that work done in Fedora is attributed to the person or client who asked for it rather than to the Preservation API itself.

Both of the Storage API’s write operations are asynchronous, and both report problems in an errors list on a result resource rather than as an HTTP error, because the failure happens long after the request returned:

  • an Import Job is queued and acknowledged with 201 Created; you poll its Import Job Result;
  • an Export is queued and acknowledged with 201 Created; you poll the Export resource.

The one exception is POST /exportMetsOnly, which runs synchronously because it copies a single small file.

Import processing runs either inside the Storage API process or in the separately deployed Storage API Importer, depending on a feature flag. Which of the two is running makes no difference to a caller. See Deployment.