Skip to main content

Documentation Index

Fetch the complete documentation index at: https://uselora.dev/llms.txt

Use this file to discover all available pages before exploring further.

Endpoint

The API is REST over HTTPS. Plain HTTP isn’t accepted.
https://api.uselora.com

Authentication

Send your API key as a Bearer token on every request:
Authorization: Bearer lora_sk_xxxx

API key

Create an API key

1

Go to your workspace

Open Profile > API Keys in your workspace.
2

Create the key

Click Create and pick the scopes this key should carry.
3

Use it

Send the key as a Bearer token on every request:
Authorization: Bearer lora_sk_xxxx

Scopes

A key carries scopes that limit what it can do. Pick the narrowest set that lets the integration work. A leaked write-everything key is much worse than a leaked read-only one.
ScopeWhat it grants
shortcuts.readRead shortcuts in the workspace.
shortcuts.writeCreate, update, and delete shortcuts in the workspace.
tags.readRead tags in the workspace.
tags.writeCreate, update, and delete tags in the workspace.
folders.readRead folders in the workspace.
folders.writeCreate, update, and delete folders in the workspace.

Errors

Every error response is JSON with the same shape. error is human-readable. requestId correlates with the X-Lora-Request-Id response header; quote it when filing a support ticket. traceId shows up when the request hit a Sentry trace. code is optional, and when present it’s a machine-readable handle you can branch on. Minimum shape:
{
  "error": "Human-readable description of what went wrong.",
  "requestId": "fra1::iad1::abc123"
}
With a machine-readable code:
{
  "error": "One or more fields failed validation.",
  "code": "validation_error",
  "requestId": "fra1::iad1::abc123",
  "traceId": "0123456789abcdef0123456789abcdef"
}

What a 401 means

The 401 body is identical whether the header is missing, malformed, the key is unknown, expired, or disabled. The API deliberately doesn’t tell you which one. Distinguishing them on the wire would let an attacker probe key validity:
{ "error": "Unauthorized", "requestId": "fra1::iad1::abc123" }
There’s no code field on the generic 401. Treat any 401 as “your request wasn’t authenticated” and check the key you sent. If the key is valid but lacks the scope an endpoint needs, you get 403 with code: "insufficient_scope" and a required_scope field naming what was missing.

Error codes

Every machine-readable code the public /v1/* routes emit. Codes are stable. A value won’t be repurposed. New codes may be added.
CodeStatusWhen
validation_error400Schema validation failed. The body includes fieldErrors keyed by field name.
invalid_json400The request body wasn’t valid JSON, or wasn’t a JSON object.
reserved_slug400The submitted shortcut slug is on the reserved list (POST /v1/shortcuts).
no_default_folder400The workspace has no live folder for the tag’s side-effect shortcut to land in (POST /v1/tags).
qr_data_too_long400The payload exceeds the capacity of the requested error correction level (GET /v1/qr).
insufficient_scope403The API key is valid but lacks the scope an endpoint needs. Body includes required_scope, e.g. "shortcuts.write".
no_permission403The API key’s user is not a member of the workspace the key is scoped to.
plan_requires_upgrade403A requested feature isn’t available on the workspace’s plan. Body includes current_plan and required_capability. Today emitted by GET /v1/qr when an anonymous caller passes hideLogo=true. The removeWatermark capability unlocks on Basic and above; Free keys can’t reach the public API at all.
folder_not_found404The supplied folderId doesn’t exist in this workspace (POST /v1/shortcuts).
tag_not_found404One or more tagIds don’t exist in this workspace (POST /v1/shortcuts, PATCH /v1/shortcuts/{slug}).
slug_conflict409A shortcut with this slug already exists in the workspace (POST /v1/shortcuts).
tag_name_exists409A tag with this name already exists in the workspace (POST /v1/tags).
shortcut_slug_exists409The tag’s auto-generated shortcut slug collides with an existing shortcut (POST /v1/tags).
folder_name_exists409A folder with this name already exists in the workspace (POST /v1/folders).
rate_limit_exceeded429The API key’s per-window request budget is exhausted. See the Retry-After header and Rate limits.
internal_error500Server-side failure. Safe to retry with backoff.

Idempotency

GET and DELETE are idempotent by definition. For POST and PATCH, send an Idempotency-Key header with a unique string so retries don’t double-write:
curl https://api.uselora.com/v1/shortcuts \
  -H "Authorization: Bearer $LORA_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "slug": "onboarding", "destination": "https://..." }'