apps/web serves a JSON API under /api/v1. The CLI is its main client; the dashboard is
the other.
This reference is generated from an OpenAPI 3.1 document derived by reading the route
handlers in
apps/web/app/api/v1 and the shared types in packages/contracts. Nothing
here is inferred from naming.It documents the surface a developer and the Myrqen CLI use. Platform-administration and
billing endpoints exist in the application but are operator-only and are deliberately not
published here — a self-hosted operator should read the route handlers directly.Base URLs
When a deployment does answer on more than one hostname,
apps/web/proxy.ts decides what
happens: the API hostname serves /api/* and nothing else, and anything else on it is
redirected to the canonical host with a 308. /api/v1/health, /api/v1/ready, and
/.well-known/* answer on any hostname, because a health check asked of a specific
hostname must not be redirected.
Conventions
JSON in, JSON out
JSON in, JSON out
Requests and responses are
application/json, except the export endpoints, which
return text/html, text/markdown, or application/json as an attachment, and the
live-progress endpoint, which returns text/event-stream.Idempotency where retries are normal
Idempotency where retries are normal
POST /api/v1/reports is idempotent on localReportId — a retry reuses the same quota
reservation and returns 200 instead of 201. POST /api/v1/projects is idempotent on
bindingPublicId.No pagination
No pagination
There is no cursor or page parameter anywhere in
/api/v1. Collection endpoints —
workspaces, projects, and a report’s shares — return the whole set.Nothing is cacheable
Nothing is cacheable
Every API response carries
cache-control: private, no-store, must-revalidate. Share
pages under /s/* do too, so a report projection is never cached under a key that
omits the viewer. The only exception is the signed update manifest, which is public and
cached for 5 minutes.Errors are a stable envelope
Errors are a stable envelope
One shape, with a stable
code to branch on and a requestId for correlating with
server logs. See Errors.Timestamps are ISO 8601 UTC
Timestamps are ISO 8601 UTC
Quota windows are UTC-anchored: the day runs 06:00 UTC to 06:00 UTC, the week runs
Monday 06:00 UTC to Monday 06:00 UTC. Never derived from a locale or from daylight
saving.
Who calls what
The CLI, with a device credential
sync-quota, workspaces, projects, reports (create, progress, upload-intent,
finalize), uploads, analytics/events, updates/manifest, and the device-link
endpoints.The dashboard, with a browser session
auth/*, device-links/{id}/approve, reading and exporting reports, the live event
stream, and sharing.Anyone with a share link
shares/slug/{slug}/report and shares/slug/{slug}/export/{format} — optionally with a
session cookie and a link password. Everything else about the report stays invisible.Nobody in particular
health, ready, device-links (bootstrap), device-links/{id}/status and
/exchange, auth/*, and updates/manifest.Request limits
A declared
Content-Length over the limit is refused before a byte is read; a chunked body
that lies about its size is refused mid-stream and the remainder is never buffered. An
over-limit body answers HTTP 413 with code BAD_REQUEST — the wire contract has no
payload-too-large code yet.
Rate limits
Every throttled surface and its budget is listed in Error codes. Two things worth knowing up front:- Login and recovery throttles are keyed on the network and the account, because a
caller who rotates
X-Forwarded-Forhas no trustworthy network identity to be throttled by.TRUSTED_PROXY_HOPSis what makes the network half meaningful at all. - Without
REDIS_URL, counters are process-local — so N replicas allow N times each limit.
Webhooks
Myrqen does not send outbound webhooks. There is one inbound webhook, for the payment provider, but it is operator-only and is not documented here. If you are configuring payments on your own deployment, see Self-host.What is not documented here
Two families of endpoint exist in the application and are deliberately withheld from this reference, because no ordinary user or CLI ever calls them:
Running your own deployment and need them? Read the route handlers under
apps/web/app/api/v1/admin and apps/web/app/api/v1/billing — they carry the reasoning in
comments. The SUPPORT_GRANT_REQUIRED error code
is still documented, because a self-hosted operator can encounter it.
Next
Authentication
Device credentials, browser sessions, and share passwords.
Errors
The envelope, the codes, and how to branch on them.