<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>An RO-Crate API Blog</title>
        <link>https://ro-crate-api.crate-works.org/blog</link>
        <description>An RO-Crate API Blog</description>
        <lastBuildDate>Tue, 21 Jul 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Deposits: write access via RO-Crates]]></title>
            <link>https://ro-crate-api.crate-works.org/blog/deposits</link>
            <guid>https://ro-crate-api.crate-works.org/blog/deposits</guid>
            <pubDate>Tue, 21 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Version 0.3.0 of the RO-Crate API specification adds deposit — the first]]></description>
            <content:encoded><![CDATA[<p>Version 0.3.0 of the RO-Crate API specification adds deposit — the first
write pathway in an otherwise read-only API. It sits in the core
specification but is optional to provide, so read-only catalogs stay
conformant. Writes flow through deposit sessions against RO-Crates: a
metadata document plus all the files it references, deposited and stored as
a unit,
from which the implementation materialises catalog entities by its own
rules.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_UsL6" id="why-ro-crates-not-entity-writes">Why RO-Crates, not entity writes<a href="https://ro-crate-api.crate-works.org/blog/deposits#why-ro-crates-not-entity-writes" class="hash-link" aria-label="Direct link to Why RO-Crates, not entity writes" title="Direct link to Why RO-Crates, not entity writes" translate="no">​</a></h2>
<p>A single RO-Crate routinely describes many catalog entities — a collection,
its items, every file they contain, and the people and organisations
connected to them; the entity model is extensible, so the list doesn't end
there. Entity-granular
write endpoints would force depositors to decompose an RO-Crate they already hold
into a sequence of per-entity calls, and force the API to referee partial
failures across that sequence.</p>
<p>The unit a depositor actually holds is the metadata document plus its files,
so that is
the unit of deposit. Depositors send RO-Crates; the implementation
materialises entities from them, and entities remain read-only projections.
How materialisation works is implementation-defined — PARADISEC turns one
item RO-Crate into an item entity plus a file entity per media file, while LDaCA
may explode a whole corpus RO-Crate into collection, item, file, person, and
organisation entities from a single deposit.</p>
<h2 class="anchor anchorTargetStickyNavbar_UsL6" id="the-deposit-session">The deposit session<a href="https://ro-crate-api.crate-works.org/blog/deposits#the-deposit-session" class="hash-link" aria-label="Direct link to The deposit session" title="Direct link to The deposit session" translate="no">​</a></h2>
<p>A deposit is a staging area with an atomic publish at the end:</p>
<ol>
<li class=""><strong>Create</strong> — <code>POST /deposits</code> opens a deposit for a new RO-Crate
(client-proposed or server-minted ID, per the declared <code>idMinting</code> mode);
<code>POST /ro-crate/{id}/deposits</code> opens an update deposit against an
existing one.</li>
<li class=""><strong>Stage</strong> — <code>PUT /deposit/{id}/metadata</code> stages the metadata document
(full replace)
and <code>PUT /deposit/{id}/file/{fileId}</code> stages files, either inline or via
a presigned upload target, in any order.</li>
<li class=""><strong>Finalise</strong> — <code>POST /deposit/{id}/finalise</code> validates and publishes
atomically, synchronously (200) or asynchronously (202 with polling via
<code>GET /deposit/{id}</code>). A failed finalise returns the deposit to <code>open</code> with
the violations recorded — staged content is never lost to a metadata typo.</li>
</ol>
<p><code>DELETE /deposit/{id}</code> aborts an open deposit.</p>
<p>Updates use metadata-as-manifest carry-forward: stage a new metadata document plus only the
changed files. Unchanged files carry forward from the pinned baseline by
<code>@id</code>, files absent from the new metadata document drop out, and each finalise replaces
the RO-Crate wholesale — the last finalise wins as a unit.</p>
<h2 class="anchor anchorTargetStickyNavbar_UsL6" id="the-read-surface-and-linkage">The read surface and linkage<a href="https://ro-crate-api.crate-works.org/blog/deposits#the-read-surface-and-linkage" class="hash-link" aria-label="Direct link to The read surface and linkage" title="Direct link to The read surface and linkage" translate="no">​</a></h2>
<p>Deposited RO-Crates are readable: <code>GET /ro-crates</code> lists them,
<code>GET /ro-crate/{id}</code> returns a lean body, and
<code>GET /ro-crate/{id}/metadata</code> returns the deposited metadata document
verbatim. The
two surfaces are bidirectionally linked — <code>entityIds</code> on the RO-Crate
answers "what did my deposit create", while <code>roCrateIds</code> on entities
and <code>roCrateId</code> on files point back at the source of truth.</p>
<p>Deletion is <code>DELETE /ro-crate/{id}</code>, plus a narrow
<code>DELETE /entity/{id}</code> valid only for entities no RO-Crate contributes
to. Deleted URIs follow a single per-implementation tombstone policy —
<code>410</code> with a <code>Tombstone</code> body, or plain <code>404</code> — declared in the new
top-level <code>tombstonePolicy</code> capability. That one is required of every
implementation, deposit or not: entities and files are mandatory core, so any
catalog can hold a URI that no longer resolves.</p>
<h2 class="anchor anchorTargetStickyNavbar_UsL6" id="discovering-write-support">Discovering write support<a href="https://ro-crate-api.crate-works.org/blog/deposits#discovering-write-support" class="hash-link" aria-label="Direct link to Discovering write support" title="Direct link to Discovering write support" translate="no">​</a></h2>
<p><code>/capabilities</code> gains a required <code>deposit</code> block. Every implementation
declares its position — a read-only catalog says so outright rather than
leaving a key out, so clients never have to read absence as a "no":</p>
<div class="language-json codeBlockContainer_p2lg theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_2noW"><pre tabindex="0" class="prism-code language-json codeBlock_iE8g thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_sZJU"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"apiVersion"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"0.3.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"deposit"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"supported"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"idMinting"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"both"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"fileUpload"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"inline"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"presigned"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"depositTtlSeconds"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">604800</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"maxFileSizeBytes"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5368709120</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>A read-only catalog declares <code>"deposit": { "supported": false }</code> and nothing
more.</p>
<p>Clients read the declared modes rather than probing, and write operations
require the new coarse OAuth2 <code>write</code> scope; finer-grained authorisation is
implementation-defined.</p>
<h2 class="anchor anchorTargetStickyNavbar_UsL6" id="where-to-go-next">Where to go next<a href="https://ro-crate-api.crate-works.org/blog/deposits#where-to-go-next" class="hash-link" aria-label="Direct link to Where to go next" title="Direct link to Where to go next" translate="no">​</a></h2>
<ul>
<li class="">The <a class="" href="https://ro-crate-api.crate-works.org/docs/deposit">Deposits guide</a> covers the model in depth, with
walkthroughs of <a class="" href="https://ro-crate-api.crate-works.org/docs/deposit/depositing">depositing</a>,
<a class="" href="https://ro-crate-api.crate-works.org/docs/deposit/updating">updating</a>, and
<a class="" href="https://ro-crate-api.crate-works.org/docs/deposit/lifecycle">deletion &amp; lifecycle</a>.</li>
<li class="">The <a class="" href="https://ro-crate-api.crate-works.org/docs/api">API reference</a> documents the deposit and RO-Crate
endpoints and schemas.</li>
<li class="">The <a href="https://github.com/crate-works/ro-crate-api/blob/main/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="">changelog</a>
records the full 0.3.0 change set.</li>
</ul>]]></content:encoded>
            <category>PARADISEC</category>
            <category>LDaCA</category>
        </item>
        <item>
            <title><![CDATA[Introducing API Extensions, /capabilities, and the segments extension]]></title>
            <link>https://ro-crate-api.crate-works.org/blog/extensions-and-capabilities</link>
            <guid>https://ro-crate-api.crate-works.org/blog/extensions-and-capabilities</guid>
            <pubDate>Mon, 06 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Version 0.1.0 of the RO-Crate API specification makes extensions first-class]]></description>
            <content:encoded><![CDATA[<p>Version 0.1.0 of the RO-Crate API specification makes extensions first-class
citizens: a curated extension registry, a new required <code>GET /capabilities</code>
endpoint for feature detection, and the first registered extension —
<code>segments</code> — which lets search hits point inside files.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_UsL6" id="why">Why<a href="https://ro-crate-api.crate-works.org/blog/extensions-and-capabilities#why" class="hash-link" aria-label="Direct link to Why" title="Direct link to Why" translate="no">​</a></h2>
<p>Archives implementing this API extend it with implementation-specific response
properties, but until now the specification had no rigorous way to define,
discover, or evolve those extensions. Portal implementers had no way to know
what a given archive supports — which extensions, or even which search facets —
without per-archive configuration or probing.</p>
<h2 class="anchor anchorTargetStickyNavbar_UsL6" id="the-extension-registry">The extension registry<a href="https://ro-crate-api.crate-works.org/blog/extensions-and-capabilities#the-extension-registry" class="hash-link" aria-label="Direct link to The extension registry" title="Direct link to The extension registry" translate="no">​</a></h2>
<p>Extensions are now specified in the OpenAPI document itself. Every extension
has a stable identifier, a schema, and semantics. Extension properties appear
inline in core schemas as optional fields, each tagged with an
<code>x-extension: &lt;id&gt;</code> annotation, so the boundary between core and extension is
machine-readable. Anyone can propose a new extension via a pull request to the
specification repository; unregistered private experiments use an <code>x-</code>
prefixed identifier.</p>
<p>Implementations choose which extensions to implement — you remain conformant
while implementing only the ones relevant to your corpus.</p>
<h2 class="anchor anchorTargetStickyNavbar_UsL6" id="get-capabilities">GET /capabilities<a href="https://ro-crate-api.crate-works.org/blog/extensions-and-capabilities#get-capabilities" class="hash-link" aria-label="Direct link to GET /capabilities" title="Direct link to GET /capabilities" translate="no">​</a></h2>
<p>Every conformant implementation now declares what it supports through a single
endpoint:</p>
<div class="language-json codeBlockContainer_p2lg theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_2noW"><pre tabindex="0" class="prism-code language-json codeBlock_iE8g thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_sZJU"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"apiVersion"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"0.1.0"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"extensions"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">"segments"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"search"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"filters"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"inLanguage"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">"type"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"string"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">"label"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Language"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token property" style="color:#36acaa">"createdAt"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">"type"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"date"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">"label"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Date created"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"facets"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">"inLanguage"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">"label"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Language"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">"mediaType"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Detection is a key lookup: an archive supports an extension exactly when its
identifier appears in <code>extensions</code>. The <code>search</code> object lets portals build
their search UI dynamically instead of hard-coding per-archive field lists:
<code>filters</code> declares the fields a search request may filter on, each with a
type (<code>string</code>, <code>date</code>, <code>number</code>, or <code>boolean</code>) that tells the portal which
UI element to render — and <code>date</code> and <code>number</code> filters accept inclusive
<code>gte</code>/<code>lte</code> range objects in search requests. <code>facets</code> declares the fields
returned with facet counts, and every facet field is guaranteed to also be
filterable, so clicking a facet value always works as a filter.</p>
<p>This is the one conformance-affecting change in 0.1.0: existing
implementations need to add the endpoint.</p>
<h2 class="anchor anchorTargetStickyNavbar_UsL6" id="the-segments-extension">The segments extension<a href="https://ro-crate-api.crate-works.org/blog/extensions-and-capabilities#the-segments-extension" class="hash-link" aria-label="Direct link to The segments extension" title="Direct link to The segments extension" translate="no">​</a></h2>
<p><code>segments</code> is the first registered extension. It adds an optional
<code>searchExtra.segments</code> array to search hits, carrying structured drill-down
locations for full-text matches inside files — a 1-based page number for PDF
matches, or an ELAN tier and time range for transcription matches — each with
highlight fragments. Portals can deep-link users straight to the matching page
of a PDF or the matching utterance in a media player.</p>
<p>Segments are a discriminated union on <code>type</code>, so generated client types give
you precise per-variant fields. New segment types arrive by spec revision, and
clients skip types they don't recognise, so deployed clients keep working as
the union grows.</p>
<h2 class="anchor anchorTargetStickyNavbar_UsL6" id="where-to-go-next">Where to go next<a href="https://ro-crate-api.crate-works.org/blog/extensions-and-capabilities#where-to-go-next" class="hash-link" aria-label="Direct link to Where to go next" title="Direct link to Where to go next" translate="no">​</a></h2>
<ul>
<li class="">The <a class="" href="https://ro-crate-api.crate-works.org/docs/extensions">Extensions guide</a> explains the extension model, the
registry, and the client rules; the <a class="" href="https://ro-crate-api.crate-works.org/docs/extensions/segments">segments page</a>
covers the first extension in depth, including implementation notes.</li>
<li class="">The <a class="" href="https://ro-crate-api.crate-works.org/docs/api">API reference</a> documents <code>/capabilities</code> and the segment
schemas.</li>
<li class="">The specification now has a
<a href="https://github.com/crate-works/ro-crate-api/blob/main/CHANGELOG.md" target="_blank" rel="noopener noreferrer" class="">changelog</a>
recording changes from 0.1.0 onwards.</li>
</ul>]]></content:encoded>
            <category>PARADISEC</category>
            <category>LDaCA</category>
        </item>
        <item>
            <title><![CDATA[First API Release]]></title>
            <link>https://ro-crate-api.crate-works.org/blog/0.1-release</link>
            <guid>https://ro-crate-api.crate-works.org/blog/0.1-release</guid>
            <pubDate>Fri, 20 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[TODO: Document the first release of our API]]></description>
            <content:encoded><![CDATA[<p>TODO: Document the first release of our API</p>
]]></content:encoded>
            <category>PARADISEC</category>
            <category>LDaCA</category>
        </item>
    </channel>
</rss>