Create a direct-to-storage upload session.
const url = 'https://api.share2.us/v1/uploads';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"source":"cli","filename":"example","size_bytes":1,"sha256":"example","content_class":"text","expires_in_hours":1,"password_protected":false,"one_time_download":false,"encrypted_client_side":false,"visibility":"public","recipient_email":"hello@example.com","targets":[{"target_device_session_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","sealed_key":"example"}],"target_device":"example","sealed_key":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.share2.us/v1/uploads \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "source": "cli", "filename": "example", "size_bytes": 1, "sha256": "example", "content_class": "text", "expires_in_hours": 1, "password_protected": false, "one_time_download": false, "encrypted_client_side": false, "visibility": "public", "recipient_email": "hello@example.com", "targets": [ { "target_device_session_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "sealed_key": "example" } ], "target_device": "example", "sealed_key": "example" }'Firebase browser callers must include a valid X-Session-Id; otherwise the API returns 401 session_required.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
private makes the share recipient-restricted from creation, EVEN WITH NO RECIPIENTS — which the gateway resolves to “only an active user of the owning account” (ADR-022). That is the “upload a file privately” case; without it the only route is upload-public-then-flip via POST /v1/shares/{id}/visibility, which leaves a live public link in between. Not plan-gated (neither is that flip). Cannot be combined with target_device or recipient_email, where a link visibility describes nothing.
Recipient email for cross-account E2E teammate delivery.
Per-recipient-device sealed content keys for teammate delivery.
object
Base64-encoded 80-byte sealed content-key envelope.
Back-compatible own-device target alias or session id.
Back-compatible own-device base64 sealed content-key envelope.
Responses
Section titled “Responses”Upload session created.
object
object
object
What the share ACTUALLY is. On the create response this is what lets a client that asked for visibility: private tell it got one: an older server ignores the field and returns a 201 with a PUBLIC link, so an ABSENT value must be read as “unknown”, never as false.
Malware scan outcome. skipped means the file was not scanned (scanning off, encrypted, or scanner unavailable) and is served with a visible warning; only a real dirty verdict blocks a share (ADR-013).
object
object
object
Example
{ "upload": { "status": "created" }, "share": { "content_class": "text", "state": "created", "scan_status": "pending" }, "upload_plan": { "method": "put" }}default
Section titled “default”Standard error envelope.
object
object
Example
{ "error": { "code": "quota_exceeded" }}