Transport basics
Base URL
Section titled “Base URL”A server is addressed by a base URL, which may contain a path: https://lager.example.com or https://example.com/inventory. All endpoints are below <base URL>/lve/v1/.
The reference app normalises what the user types: it trims spaces, adds https:// when no scheme is given, removes trailing slashes and accepts only http and https URLs with a host. lager.example.com:8443 becomes https://lager.example.com:8443.
| Endpoint | Auth | Purpose |
|---|---|---|
GET /lve/v1/info |
no | Discovery |
POST /lve/v1/auth/token |
no | Sign in with credentials |
POST /lve/v1/auth/pair |
no | Sign in with a pairing code |
DELETE /lve/v1/auth/token |
yes | Sign out |
POST /lve/v1/sync/push |
yes | Push changes |
GET /lve/v1/sync/pull |
yes | Pull changes |
HEAD, GET, PUT /lve/v1/attachments/{sha256} |
yes | Attachments |
POST /lve/v1/number-ranges/{key}/reserve |
yes | Number ranges |
HTTPS and local networks
Section titled “HTTPS and local networks”Servers reachable over the internet MUST use HTTPS with a certificate the client's platform trusts. Tokens, passwords and inventory data travel in every request.
Plain HTTP is acceptable only inside a trusted local network. The iOS reference app allows plain HTTP only to hosts that App Transport Security treats as local (for example .local names and addresses in the local network) and asks the user for local network access the first time. Everything else needs HTTPS.
Requests and responses
Section titled “Requests and responses”- Request and response bodies are JSON in UTF-8,
Content-Type: application/json, except attachment bodies, which are raw bytes. - Clients send
Accept: application/json. - Clients send
Authorization: Bearer <token>on every endpoint exceptinfoand the two sign-in calls. - A request body declared as JSON that does not parse is answered with
400andmalformed_request. - JSON objects in payloads stay objects. A server written in a language whose JSON decoder turns
{}into an empty array (PHP with associative decoding, for example) MUST decode payloads so that empty objects survive, because the payload is relayed to other clients unchanged. The reference server decodes pushed changes into objects for this reason.
Language
Section titled “Language”Clients send Accept-Language with de or en. The reference app sends de when the device's preferred language is German and en otherwise.
Servers answer error.message and the message of rejected changes in that language and name it in the Content-Language response header. The reference server supports de and en, uses German when the header is missing or names neither, and localises every error below /lve, including 404 and 405 for unknown addresses.
Messages are for people. Clients MUST decide by error.code or by the push reason, never by message.
Rate limits
Section titled “Rate limits”Any endpoint may answer 429 with too_many_requests. Clients wait at least the number of seconds in Retry-After (when present) before trying again.
The reference server limits only the two sign-in endpoints: together 10 requests per minute per client IP address. Their responses carry X-RateLimit-Limit and X-RateLimit-Remaining; a 429 also carries Retry-After.
Timeouts and retries
Section titled “Timeouts and retries”The reference app waits at most 15 seconds for a response to start and 120 seconds for a whole request (also for attachment uploads). On a timeout or a transport error it marks the device offline and retries with the next sync trigger, typically within a minute.
Every request in the protocol can be repeated safely:
| Request | Why a repeat is harmless |
|---|---|
| push | Changes that were stored are answered ignored the second time |
| pull | Pulling from the same cursor returns the same changes; merging them again changes nothing |
| attachment upload | Content-addressed; a second upload is answered 200 |
| number reservation | A repeat reserves new numbers; the numbers of the lost response stay unused (a gap) |
| sign-in | A repeat issues a new token and revokes the previous one of the same device |
A server SHOULD process a push request even if the client disconnects, and MUST NOT leave a change half stored.
Versions
Section titled “Versions”The path prefix carries the major version. A server that supports version 2 in the future serves it below /lve/v2/ and lists both versions in info.versions. Clients pick the highest version both sides support.