Skip to content

Public API

Looped’s public API is the same surface the apps use — exposed for external integrations.

It lives at api.looped.sh. That URL renders the interactive Scalar reference — every endpoint, every parameter, every response shape, with a “Try it” panel you can run live calls from.

For machine consumption, the OpenAPI 3.0 spec is at api.looped.sh/openapi.json. Drop it into Postman, Bruno, or your codegen of choice.

Every request needs an API key in the X-API-Key header. Generate one from your team’s API keys page, then:

Terminal window
curl https://api.looped.sh/v1/invoices \
-H "X-API-Key: looped_..."

The key carries the team scope — you don’t pass teamId separately. Each key also carries a scope set (read-only / write / restricted) configured when the key was created.

StatusCause
200 / 201Success
400Validation error — body explains the offending field
401Missing / invalid / expired / revoked X-API-Key
403Key is valid but doesn’t include the scope this endpoint needs
404Resource not found (or in a different team)
Path prefixResource
/v1/invoicesInvoices, line items, marking statuses, generating PDFs
/v1/invoices/clientsClients (the “billed to” side of invoices)
/v1/track/timeTime entries
/v1/track/projectsProjects
/v1/track/sectionsSections within a project
/v1/track/tagsTags on time entries

The exact list and response shapes are authoritative in the live reference.

Requests are rate-limited per API key. If you exceed the limit you’ll get a 429 with a Retry-After header. Most well-behaved integrations never hit it.

Mutating endpoints (POST/PATCH/DELETE) are not idempotent by default. If you need at-most-once semantics for a workflow that might retry, dedupe on your side or use a deterministic id pattern in your application logic.

We don’t ship official SDKs yet. Generate one for your language from the OpenAPI spec — most popular languages have a one-shot generator (openapi-generator, swagger-codegen, etc.) that produces a usable client in a couple of minutes.