oxen push and oxen workspace add
use for large files: you begin an upload with the file’s hash and size, and the server tells you how
to split it into parts. Each part is its own request, and the server stores each one as it arrives,
then checks the whole file against its hash once the last part is in.
It also does something the single-request upload can’t: stage the file directly into a
workspace, so it’s ready to commit, or to read back,
without ever committing it.
A file may be at most 1 TiB (1,099,511,627,776 bytes). This limit is provisional, and will be
raised when users need larger files.
The two steps
Both take your API key as a bearer token:
The hash identifies the file
You begin an upload with the XXH3-128 hash of the file’s complete contents, written as hexadecimal. The server checks the bytes it receives against that hash before the file becomes visible, so a wrong hash gets the upload rejected, and a right one guarantees the server stored exactly what you sent.For files large enough that you don’t want them in memory, hash incrementally: every XXH3
implementation supports feeding it the file in pieces.
Step 1: Begin the upload
Send the file’s hash and size, and, to stage the file into a workspace, adestination.
Request
Response
The response’sfile field says whether to send parts.
When
file is already_stored, there is nothing to send: the server has the file, and has already
staged it at the destination if you gave one. The other fields are absent.
Step 2: Send the parts
Send partn as the raw bytes of the file from byte (n - 1) * part_size, part_size bytes long
except for the last part. The body is not multipart, and not JSON.
Request
"completed": true, once the whole file matches its hash and is
staged at the destination, if the upload has one.
Sending parts in parallel
Parts may arrive out of order, but only so far ahead: a part is accepted while its number is less than the first part not yet checked pluspart_window. Send parts in order and keep no more than
part_window of them in flight, and every part fits.
A part the server cannot take yet gets 429 Too Many Requests with a Retry-After header, the
seconds to wait before sending it again. That happens when a part arrives too far ahead, or while an
earlier copy of the same part is still being stored.
When a response is lost
Send the part again. A part the server already stored is accepted and ignored, so a repeat is always safe. A part sent after the upload has completed gets 404 Not Found, as does any part of an upload the server aborted, which happens after a minute with no part arriving. On a 404, begin the upload again: if the file completed, begin answersalready_stored, and if it was aborted, begin starts a new
upload.
Errors
On Oxen.ai, beginning an upload that would take you past your storage quota gets 402 Payment
Required.
Complete example
Uploads a file in parts and stages it into a workspace, sending one part at a time.Python
When to use this
Reach for an upload session when any of these is true:- The file is larger than one request can carry. The most common reason. Serverless platforms in particular cap request bodies at a few megabytes.
- You want a failure to cost one part, not the whole file. A part is sent again on its own.
- You want parallelism. Up to
part_windowparts can be in flight at once. - You want the file staged but not committed. A
destinationputs it in a workspace, where you can read it back or throw it away without touching history.
Older clients upload large files through
POST /versions/{hash}/create,
PUT /versions/{hash}/chunks, and POST /versions/{hash}/complete. Those endpoints are deprecated
and will be removed in a future release, so use upload sessions for new code.