CLI device flow
The CLI’s browser login uses the device authorization grant
(RFC 8628). It lets a terminal — even a
headless one over SSH — obtain an API key by having you approve in a browser,
without pasting a long secret into the shell. You normally trigger it with
loomta auth:login; this page documents the underlying endpoints if you want to
build your own client.
The flow at a glance
Section titled “The flow at a glance” CLI Loomta API Browser (you) │ │ │ │ POST /auth/device/start │ │ │ ─────────────────────────────► │ │ │ ◄───── device_code, │ │ │ user_code, URIs │ │ │ │ │ │ show user_code + open URL ───────────────────────────────► │ │ │ POST /auth/device/approve │ │ │ ◄─────────────────────────── │ (session + org) │ │ mints loomta_sk_… key │ │ POST /auth/device/token │ │ │ (poll every `interval`s) ───► │ │ │ ◄───── authorization_pending │ │ │ … │ │ │ ◄───── { api_key } │ (returned exactly once) │ ▼ ▼ ▼Step 1 — Start
Section titled “Step 1 — Start”curl -X POST https://api.loomta.com/auth/device/start \ -H "Content-Type: application/json" -d '{}'{ "device_code": "…secret…", "user_code": "LMT-7QX2-9KFP", "verification_uri": "https://loomta.com/cli-auth", "verification_uri_complete": "https://loomta.com/cli-auth?code=LMT-7QX2-9KFP", "interval": 5, "expires_in": 600}device_code— your secret; keep it to poll with. Never shown to the user.user_code— theLMT-XXXX-XXXXcode the user confirms in the browser.verification_uri/…_complete— where to send the user. The_completeform pre-fills the code.interval— minimum seconds between polls (5).expires_in— the codes are valid for 600 seconds (10 minutes).
Step 2 — User approves in the browser
Section titled “Step 2 — User approves in the browser”Open verification_uri_complete. The user signs in (if needed), picks a
workspace, and authorizes. Under the hood the web app calls:
POST /auth/device/approveAuthorization: Bearer <session-token>x-organization-id: <workspace-uuid>
{ "userCode": "LMT-7QX2-9KFP" }This mints a new loomta_sk_… key scoped to the chosen workspace and binds it to
the pending request. (This call is made by the Loomta web app, not by your CLI.)
Step 3 — Poll for the key
Section titled “Step 3 — Poll for the key”Poll no faster than interval:
curl -X POST https://api.loomta.com/auth/device/token \ -H "Content-Type: application/json" \ -d '{ "device_code": "…secret…" }'While the user hasn’t approved yet, you get HTTP 400 with one of these
error values (RFC 8628 §3.5):
error |
Meaning | What to do |
|---|---|---|
authorization_pending |
Not approved yet. | Keep polling at interval. |
slow_down |
You polled too fast. | Add 5s to your interval, continue. |
expired_token |
The 10-minute window elapsed. | Start over with /start. |
access_denied |
Denied, invalid, or already claimed. | Stop; restart if needed. |
On success you get 200 once:
{ "status": "approved", "api_key": "loomta_sk_…" }Just use the CLI
Section titled “Just use the CLI”Unless you’re writing your own client, you don’t need any of this — run:
loomta auth:login # opens the browser, polls, saves the keyloomta auth:login --no-browser # headless: prints the URL + code insteadSee CLI authentication for all three login methods.