LA2L for developers

The REST API

Every SDK makes the same five kinds of calls, and any language can make them: pair once, announce a package, upload its files, commit, and follow it. JSON in and out, over HTTPS, without an API key.

Base address: https://lloydstellar.nl/la2l/api

For machines: openapi.yaml (OpenAPI 3.1) describes every call, answer and error text, and app2live-1.schema.json (JSON Schema) the package description.

From a script

With Node.js 22.12 or newer, the command line of @lloydstellar/la2l does it all:

npx @lloydstellar/la2l pair K7P42Q
npx @lloydstellar/la2l send kick.wav snare.wav --loop --bpm 92 --role drums --title "Beat" --wait
npx @lloydstellar/la2l status

--oneshot for sounds that play as they are. It keeps the token in a file only the user can read, or takes it from LA2L_TOKEN.

The five calls, with curl

BASE=https://lloydstellar.nl/la2l/api

# 1. Pair, with the code LA2L shows in Live. Keep app_token like a password.
curl -sS -X POST $BASE/pair/claim -H 'Content-Type: application/json' \
  -d '{"code":"K7P 42Q","app_name":"curl test","app_id":"curl-1"}'
#   -> {"app_token":"la2la_...","device_name":"STUDIO-PC"}
TOKEN=la2la_...

# 2. Announce the package, with bytes and sha256 of every file
BYTES=$(wc -c < kick.wav | tr -d ' '); SHA=$(shasum -a 256 kick.wav | cut -d' ' -f1)   # shasum: macOS and Linux
curl -sS -X POST $BASE/packages -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{
  "schema": "app2live/1", "title": "Curl test", "source": {"app": "curl test"}, "tempo": {"bpm": 120},
  "items": [{"id": "kick", "file": "kick.wav", "name": "Kick", "kind": "loop", "role": "drums",
             "bytes": '"$BYTES"', "sha256": "'"$SHA"'"}]}'
#   -> {"package_id":"<id>","upload":{"kick.wav":"/packages/<id>/files/kick.wav"},...}

# 3. Upload, 4. commit, 5. follow
curl -sS -X PUT "$BASE/packages/<id>/files/kick.wav" -H "Authorization: Bearer $TOKEN" --data-binary @kick.wav
curl -sS -X POST "$BASE/packages/<id>/commit" -H "Authorization: Bearer $TOKEN"
curl -sS "$BASE/packages/<id>/status" -H "Authorization: Bearer $TOKEN"
#   -> {"status":"waiting",...} until Import in Live, then {"status":"imported",...}

Rules for every call

The calls

CallDoes
POST /pair/claim{"code", "app_name", "app_id"}: trades the code from Live for {"app_token", "device_name"}. A wrong, used or expired code: 404.
GET /app/me{"device_name", "app_name", "paired_at"}: which computer this app is paired with.
POST /app/unpairRevokes this token.
POST /packagesThe package description, with bytes and sha256 of every file. 201 with package_id, the upload path per file and warnings. 422 with the reason when LA2L would refuse it.
PUT /packages/{id}/files/{file}The bytes of one WAV file, up to 200 MB. Checked against its size, checksum and WAV header.
POST /packages/{id}/commitEvery file is there: from now on Live sees the package. 409 names the files still missing.
GET /packages/{id}/statusuploading, waiting, imported, partial, failed or expired, with the result per sound after Import.
DELETE /packages/{id}Takes a package back, until it is in Live.

Upload the files and commit within an hour. A package waits 24 hours for Import; then it is deleted, imported or not. Its status stays readable for 7 days.

The package description itself: The package description.