LaserData Cloud
API Reference

Authentication

How to authenticate requests to the LaserData Cloud API using API keys and scoped roles.

API Variables
ld-api-key
{tenant_id}

Set variables to auto-fill all examples and run requests in-browser.

All LaserData Cloud API requests are authenticated using API keys passed in the ld-api-key request header. There are no sessions, cookies, or OAuth flows for API access.

Request Header

bash
curl https://api.laserdata.cloud/tenants/{tenant_id}/api_keys \
-H "ld-api-key: YOUR_API_KEY"

The key is validated on every request. If the key is missing, expired, or invalid, the API returns 401 Unauthorized. If the key is valid but lacks the required permission, the API returns 403 Forbidden.

Key Format

API keys are long-entropy random secrets. They cannot be recovered after creation; only the hash is stored server-side. Copy the secret immediately after creating it.

Scopes and Permissions

Every API key is tied to a role, which defines its permissions. Roles grant access at two levels:

ScopeDescription
TenantCross-organization permissions, for example member:read, api_key:manage
DivisionResource permissions scoped to specific environments, for example deployment:manage, deployment:config:read

The full permission model is documented in Roles & Permissions.

When creating an API key you can either assign an existing role or define inline permissions (a dedicated role is created automatically).

Rate Limiting

Each API key has a per-key rate limiter. Exceeding the limit returns 429 Too Many Requests. The response includes Retry-After indicating when the limit resets.

IP Allowlisting

API keys support optional IP allowlisting. When an allowlist is configured, requests from IPs not in the list receive 403 Forbidden regardless of the key's validity.

Allowlists can be updated on existing keys without recreating them. See Update API Key Security.

Expiry

All API keys have a mandatory expiration date (maximum 365 days). Expired keys return 401 Unauthorized. Create a replacement key before expiry and rotate it in your CI/CD environment.

Error Reference

StatusCause
400 Bad RequestValidation failed. Response includes field_issues[] with per-field details
401 UnauthorizedKey missing, malformed, expired, or revoked
403 ForbiddenKey valid but missing the required permission, or request from a blocked IP
404 Not FoundResource does not exist or is not visible to this key
429 Too Many RequestsPer-key rate limit exceeded; check Retry-After
500 Internal Server ErrorUnexpected server failure

Error Envelope

Every non-2xx response uses a single envelope, served as application/problem+json and modelled on RFC 7807:

{
  "type": "about:blank",
  "title": "Invalid Email",
  "code": "invalid_email",
  "reason": "Invalid email address",
  "instance": "8f4a2b6c9d1e4f3a8b5c7d9e0f1a2b3c",
  "field": "email",
  "field_issues": [
    {
      "code": "invalid_email",
      "reason": "malformed address",
      "path": "email"
    }
  ],
  "status": 400,
  "retryable": false
}

The instance value mirrors the ld-request response header (simple-form UUID, 32 hex chars).

FieldDescription
typeRFC 7807 type URI for the error class. about:blank when no type is registered
titleShort human-readable title derived from code (acronyms capitalised)
codeStable machine-readable error code (e.g. invalid_email, tenant_not_found, insufficient_permissions)
reasonLong-form human explanation of this occurrence
instanceMirrors the ld-request response header. Quote this when filing a support ticket
fieldSingle field name when the error is bound to one field. Still emitted for back-compat
field_issuesArray of per-field issues for validation errors. Each entry has code, reason, and an optional dotted path. Omitted on non-validation errors
statusMirror of the HTTP status code so agents can branch on the body without re-reading the response status
retryabletrue for retryable conditions (408, 425, 429, 500, 502, 503, 504), false otherwise

Validation errors return 400 with one or more entries in field_issues so clients can surface per-field UI feedback.

API Keys vs Console Sessions

Two security schemes are advertised across the OpenAPI specs: ld_api_key (tenant-scoped API key) and session_cookie (Console browser session). Most endpoints accept either, but user-scope paths reject API keys even when the key was created by the same user.

API key requests on these paths return 403 Forbidden with code: api_key_not_allowed. The closed set covers operations bound to a human session: account read, account export, sign-out, listing your own sessions, invitation accept and reject, listing your own invitations, user activity, tenant creation, leaving a tenant, and tenant deletion. Use a Console-issued cookie session for these.

Security Best Practices

  • Store keys in secrets managers (AWS Secrets Manager, HashiCorp Vault, GitHub Secrets), never in source code or logs
  • Use the minimum required permissions: prefer deployment:read over a full admin role for read-only automation
  • Set short expiration windows for CI keys (30-90 days)
  • Enable IP allowlisting for long-lived keys used from fixed infrastructure
  • Rotate keys using zero-downtime overlap: create the new key, update all consumers, then delete the old key
  • All API key operations are logged in the audit trail

On this page