The Git LFS protocol is small: four routes, plus a health check:

Method Path Purpose
POST /{org}/{repo}/objects/batch negotiation: the client announces its objects, the server answers per object with an upload or download link
PUT /{org}/{repo}/objects/{oid} store an object
GET /{org}/{repo}/objects/{oid} retrieve an object, whole or by Range
POST /{org}/{repo}/objects/verify post-upload verification
GET /{org}/{repo} a page showing what the repository holds
GET /{org}/{repo}/objects/stats the same numbers as JSON
POST /{org}/{repo}/objects/retain reclaim space, see Reclaiming space
POST /{org}/{repo}/objects/dedupe fold objects stored before the shared store into it
POST /{org}/{repo}/objects/compress fold objects stored before compression into it
POST /{org}/{repo}/objects/audit read every object back and check it against its own digest
POST /{org}/{repo}/locks take a lock on a path
GET /{org}/{repo}/locks list locks, filterable by path or id
POST /{org}/{repo}/locks/verify the client's own locks, and everyone else's
POST /{org}/{repo}/locks/{id}/unlock release a lock
GET /-/api/overview the dashboard's figures, for a signed-in session or a forge admin's token
GET, PUT, DELETE /-/api/access read, save or reset the access settings the dashboard edits
POST, GET, DELETE /-/api/session sign in to the dashboard with a token, see who is signed in, sign out
GET /metrics Prometheus exposition
GET /health liveness: the process is up
GET /ready readiness: the storage root is writable

Objects already present are returned by batch with no actions, so the client skips re-uploading them. Missing objects on a download are reported per object with a 404 error rather than failing the whole batch.

Downloads honour Range, so a transfer that drops at 90% of a three-gigabyte asset resumes from where it stopped instead of starting over, which on a home upstream is the difference between an annoyance and an afternoon. A range that cannot be satisfied is refused with 416 carrying the object's real size; a range we cannot parse is ignored and the whole object is served, since refusing a transfer over a malformed header would be worse than the header.