Adds another file to a share.
Why files arrive one at a time
A request carrying five files loses all five when it drops at the fourth, which is what uploading a folder of photos over a home connection runs into. A file that fails here is retried alone.
Why the share exists before its second file
There is no draft state. A share is created by its first file and grown by the rest, so nothing has to be finalised, and an interrupted upload leaves a share with what did arrive instead of nothing.
The cost is that a link opened mid-upload shows a partial share. The uploader hands out the link afterwards.
Errors
400 for a name that is unusable or described the wrong way for the share,
403 when the caller cannot show it is theirs, 404 when no share has that
code, 409 when the share holds text, 413 when the body is too large,
507 when something is out of room. The body says whose limit it was.
tessera_session<token>Set by POST /auth/login. A browser sends it automatically; it is HttpOnly, so page scripts cannot read or set it.
code*stringThe share to add to
filename?stringWhat to call this file.
sealed_name?stringIts name and media type, sealed, when the share is encrypted. Replaces
filename there.
The file
application/octet-stream- body
[index: integer]?integerint320 <= valueThe share as it now stands
application/json- response
A share as the API describes it. Never carries the content.
code*stringThe retrieval code, as a person reads it.
copy_count*integerHow many times a client reported it being copied.
int320 <= valuecreated_at*stringWhen it was created, RFC 3339.
disabled*booleanWhether it has been switched off, by an operator or because the scanner
found a threat. A disabled share answers 404 to everyone else.
encryption?|link or password for an end-to-end encrypted share, null for one
the server can read.
expires_at?|When it stops being served, RFC 3339, or null to live until deleted.
files*array<>Every file this share holds. Empty for text and for a locked share.
has_password*booleanWhether a password must be presented to retrieve it.
id*stringStable identifier.
key_salt?|The salt a password-derived key was stretched with, for password.
kind*stringtext, file or link.
language?|Syntax-highlighting hint.
last_accessed_at?|When it was last retrieved, RFC 3339.
Answers the question people ask of their own share: has it been picked up yet?
management_token?|Token that lets an anonymous uploader delete this share.
Shown once, at creation, and only for an anonymous upload. Only its digest is stored. Without it, a mistaken anonymous upload could never be taken back.
path*stringWhere the share lives, relative to this instance's origin.
Relative by design. The server does not know what host it is reached through, and guessing wrong behind a reverse proxy produces broken links. The caller already knows the origin it called.
scan_detail?|The threat's name for infected; encrypted or too_large for
skipped.
scan_state?|The malware scanner's verdict, the most significant across its files:
pending, clean, infected, skipped or deferred. null when it
was never sent to a scanner. See docs/scanning.md.
scanning*booleanWhether it is waiting for the malware scanner. Until it is done,
downloads answer 423 with Retry-After.
sealed_details?|The title and a note's language, sealed, on an encrypted share.
size_bytes*integerSize of the content in bytes.
int640 <= valuetitle?|Display name.
use_count*integerHow many times it has been retrieved.
Counted by the server on the transfer path, so this is the number to trust. The two below are what a client reported.
int320 <= valueuses_remaining?|How many retrievals remain, or null for unlimited.
int320 <= valueview_count*integerHow many times a client reported showing it.
int320 <= valuecurl -X POST 'https://example.com/api/v1/shares/string/files?filename=holiday.jpg' \ -H 'Content-Type: application/octet-stream' \ -d '<0>0</0>'{ "code": "string", "copy_count": 0, "created_at": "string", "disabled": true, "encryption": "string", "expires_at": "string", "files": [ { "filename": "string", "position": 0, "sealed_name": "string", "size_bytes": 0 } ], "has_password": true, "id": "string", "key_salt": "string", "kind": "string", "language": "string", "last_accessed_at": "string", "management_token": "string", "path": "string", "scan_detail": "string", "scan_state": "string", "scanning": true, "sealed_details": "string", "size_bytes": 0, "title": "string", "use_count": 0, "uses_remaining": 0, "view_count": 0}