loadmento protocol icon
← The lumento family

loadMENTO

The protocol underneath the lumento family. Its full name is the Loadmento Import Protocol, or LIP. It's how a device sends photos and video to lumento STORE and gets back an answer it can trust: this file is on the NAS, it's byte-identical to yours, and it was already there or it's now written to disk.

HTTPS + JSONVersion 1.1Spoken by LOAD and ONE
How a Load works

The NAS says what it needs.
Then the bytes move.

Control calls are HTTPS with JSON bodies. Uploads are the raw file bytes, sent whole or in chunks. A session goes like this:

POST /sessions                     start a session
POST /sessions/{id}/assets         announce up to 1,000 assets
  ← upload | skip_duplicate | skip_already_received
PUT  …/resources/{rid}             whole file, under 25 MiB
PUT  …/resources/{rid}/chunks/{n}  8 MiB chunks, 25 MiB and up
POST /sessions/{id}/finish
GET  /sessions/{id}/report         the import report
  1. Announce before any bytes. The device lists each file with its SHA-256. For each one the NAS answers upload, skip, duplicate or skip, already received. Files the NAS already has aren't sent again.
  2. Upload. Small files go in a single request. Large files go in 8 MiB chunks, each with its own hash, so one bad chunk means resending one chunk. Chunks can safely be resent, so a device that isn't sure whether a chunk arrived just sends it again.
  3. Check and store. The NAS hashes the bytes that actually arrived. If they match, the file is written to disk and moved into place in one step. If they don't, it's never stored.
  4. Deferred commits. For a very large video, the NAS may answer “accepted, still writing” and give the final result on a later call. A client never reports success before it has that result.
Design principles

Small, strict and written down.

The server decides

Duplicate checks, naming, where files go and name collisions are all handled by the NAS. A client only sends bytes, a filename and what it knows about the date.

Not tied to one client

The iPhone app and lumento ONE's camera-card import are both ordinary paired devices. Nothing in the protocol assumes a particular one, so a new client, such as a command-line tool, is meant to be a small job, not a redesign.

Paired, not open

Pairing starts on the NAS with a six-digit code and works only on the local network. The code never crosses the network: the device and the NAS each prove they know it (SPAKE2+, with spake2p, a pairing library we wrote for lumento and publish under the MIT and Apache 2.0 licences), so anyone listening learns nothing they could test guesses against. Each code works for one try, and the device fixes the NAS's certificate as part of the exchange. The token is never sent in the clear.

Errors that tell you what to do

Errors come back as structured JSON with a stable code. A client treats an error code it doesn't recognise as temporary, and the spec defines the retry schedule, so every client backs off the same way.

Upload only

The protocol can add to the archive and report on it. It has no way to delete anything already archived.

Suited to iOS background uploads

Every upload is a plain HTTPS request with a file body, which is exactly what iOS's background upload service needs. Uploads keep going while the phone is locked.

For implementers

A spec you can test against.

One source of truth. The protocol is defined in a single document. Every copy elsewhere is a read-only snapshot that can be checked against it.

The server returns its own spec. A running lumento STORE answers GET /protocol.md with the version of the protocol document built into it. You can see exactly what the NAS in front of you implements, even if it's running an older build.

Test fixtures from the real server. The spec comes with a set of example requests and responses. They were recorded from the server's own code, not written by hand, so you can test a client against what the server actually does. Recording them turned up three places where the prose was wrong, and all three were fixed.

Capabilities, not guesses. GET /capabilities tells a client what this server supports before it starts.