Share links
StableGenerated from capsule-server/openapi.json, the OpenAPI 3.2 document
capsule-server emits and mise run openapi-check-kynos keeps current. To change a
description on this page, change the annotation on the handler or model it comes from
and regenerate — this file is build output. The auth model, error contract, and
conventions common to every endpoint are on the REST API overview.
GET /s/{opaque_id}
Section titled “GET /s/{opaque_id}”What a viewer needs to begin, for a live link.
Authentication: none.
| Parameter | In | Type | Description |
|---|---|---|---|
opaque_id | path | string | Required. The opaque id. |
| Status | Body | Description |
|---|---|---|
200 | SharedMetadataResponse application/json | OK. |
400 | CodedProblem application/problem+json | Bad Request. |
404 | CodedProblem application/problem+json | Not found. |
413 | — | the request body exceeds the configured limit. |
429 | CodedProblem application/problem+json | Too many requests. |
500 | CodedProblem application/problem+json | Internal server error. |
GET /s/{opaque_id}/blob/{hash}
Section titled “GET /s/{opaque_id}/blob/{hash}”Ciphertext for one of the link’s blobs, ranged.
The membership check is the security property: a link serves the addresses its record
enumerates and nothing else, so it cannot be walked sideways into the album’s unstripped
metadata. A blob the link does not name is the same 404 as a link that does not exist.
Authentication: none.
| Parameter | In | Type | Description |
|---|---|---|---|
If-Modified-Since | header | string | The date the client’s copy carries, per RFC 9110 section 13.1.3. |
If-None-Match | header | string | The entity tag the client already holds, per RFC 9110 section 13.1.2. |
If-Range | header | string | The entity tag the client’s partial copy came from, per RFC 9110 section 13.1.5. The Range is honoured only if it matches this representation under the strong comparison; otherwise the whole representation is sent. |
Range | header | string | The part of the representation to transfer, per RFC 9110 section 14.2. A field this operation cannot apply is ignored and the whole representation is sent. Example: bytes=0-1023. |
hash | path | string | Required. The blob’s content address. |
opaque_id | path | string | Required. The opaque id. |
| Status | Body | Description |
|---|---|---|
200 | string application/octet-stream | the whole representation. Headers: Accept-Ranges, ETag, Last-Modified. |
206 | string application/octet-stream | the part the request asked for. Headers: Accept-Ranges, Content-Range, ETag, Last-Modified. |
304 | — | the client’s copy is current. Headers: ETag, Last-Modified. |
400 | CodedProblem application/problem+json | Bad Request. |
404 | CodedProblem application/problem+json | Not found. |
413 | — | the request body exceeds the configured limit. |
429 | CodedProblem application/problem+json | Too many requests. |
500 | CodedProblem application/problem+json | Internal server error. |
GET /s/{opaque_id}/wrapped-secret
Section titled “GET /s/{opaque_id}/wrapped-secret”The passphrase-wrapped scope material, when there is one.
A link with no passphrase answers 404 rather than 204 or an empty body: whether a link is
passphrase-protected is already disclosed by the metadata record, and a second way to ask
the same question with a different shape is a second thing to keep consistent.
Authentication: none.
| Parameter | In | Type | Description |
|---|---|---|---|
opaque_id | path | string | Required. The opaque id. |
| Status | Body | Description |
|---|---|---|
200 | string application/octet-stream | OK. |
400 | CodedProblem application/problem+json | Bad Request. |
404 | CodedProblem application/problem+json | Not found. |
413 | — | the request body exceeds the configured limit. |
429 | CodedProblem application/problem+json | Too many requests. |
500 | CodedProblem application/problem+json | Internal server error. |
POST /v1/shares
Section titled “POST /v1/shares”Register a share link the caller’s client has issued.
Authentication: required — bearer.
Request body (required, application/json): IssueShareRequest
| Status | Body | Description |
|---|---|---|
201 | IssueShareResponse application/json | The share link is registered and servable. |
400 | CodedProblem application/problem+json | Bad Request. |
401 | CodedProblem application/problem+json | Unauthorized. Headers: WWW-Authenticate. |
403 | CodedProblem application/problem+json | Forbidden. |
413 | — | the request body exceeds the configured limit. |
415 | CodedProblem application/problem+json | Unsupported Media Type. |
422 | CodedProblem application/problem+json | Unprocessable Entity. |
500 | CodedProblem application/problem+json | Internal server error. |
DELETE /v1/shares/{opaque_id}
Section titled “DELETE /v1/shares/{opaque_id}”Revoke one of the caller’s links.
Idempotent from the caller’s side and indistinguishable: a link that was never theirs, a
link that does not exist, and a link they already revoked are all 204. Revocation is the
one operation where saying “there was nothing to revoke” would be a lookup.
Authentication: required — bearer.
| Parameter | In | Type | Description |
|---|---|---|---|
opaque_id | path | string | Required. The opaque id. |
| Status | Body | Description |
|---|---|---|
204 | — | the request succeeded and there is no content to send. |
400 | CodedProblem application/problem+json | Bad Request. |
401 | CodedProblem application/problem+json | Unauthorized. Headers: WWW-Authenticate. |
403 | CodedProblem application/problem+json | Forbidden. |
413 | — | the request body exceeds the configured limit. |
500 | CodedProblem application/problem+json | Internal server error. |
Schemas
Section titled “Schemas”The models these endpoints carry. A field whose type names another model links to it when this page documents that model, which it does when some path from an operation reaches it within 4 references. A model only ever reached deeper than that is named without being expanded.
CodedProblem
Section titled “CodedProblem”An RFC 9457 problem detail.
| Field | Type | Description |
|---|---|---|
type | string | Required. |
title | string | — |
status | integer | Required. |
detail | string | — |
instance | string | — |
code | string | Required. The stable error.* catalog code. The client localizes this; detail stays English. Present on every problem this server renders. |
IssueShareRequest
Section titled “IssueShareRequest”A link the owner’s client has issued.
| Field | Type | Description |
|---|---|---|
opaque_id | string | Required. The 128-bit opaque id, 32 lowercase hex characters, drawn from the client’s CSPRNG. Minted by the client rather than the server because the client is what knows the fragment secret the id is paired with; the server checks its shape and stores it. |
metadata_hash | string | Required. The metadata blob a viewer starts from. Must appear in serves. |
serves | string[] | Required. Every blob this link may serve, and nothing else. Enumerated by the issuing client, which is what makes the boundary-crossing strip stick: the client points the link at blobs it prepared for export, and the server has no path from an opaque id to anything outside this set. |
wrapped_secret | string | null | The passphrase-wrapped scope material, base64, when the link is passphrase-protected. Opaque to this server. The passphrase never crosses the wire — unwrap is client-side. |
expires_at | string | null | When the link stops being live, RFC 3339. Absent means no expiry. |
IssueShareResponse
Section titled “IssueShareResponse”Confirmation that a link is now servable.
| Field | Type | Description |
|---|---|---|
opaque_id | string | Required. The opaque id, echoed. |
SharedMetadataResponse
Section titled “SharedMetadataResponse”What a viewer needs to start.
| Field | Type | Description |
|---|---|---|
metadata_hash | string | Required. The metadata blob’s content address; fetch it from /s/{opaque_id}/blob/{hash}. |
passphrase_protected | boolean | Required. Whether a passphrase is required before the scope material can be opened. The one property of the link this path discloses, and it has to: a viewer cannot know to ask for a passphrase otherwise. It says nothing about what the link points at. |