Skip to main content
datumctl api proxy starts a local HTTP proxy that forwards every request to the Datum Cloud API endpoint of your session, adding your credentials automatically and refreshing them as needed. Point any local tool — a dev server, a test harness, curl — at the printed URL and it can talk to the platform with no tokens to copy and no expiry to manage.
Running in CI or an unattended pipeline? Use a service account for the session the proxy serves — the proxy carries whatever identity you are logged in as.

Start the proxy

By default the proxy picks a random free port, so starting a second proxy never fails. Two things are always printed once the listener is ready:
  • A human-readable banner on stderr names the session, upstream, scope, and listen address, so you can verify at a glance whose credentials the proxy serves.
  • The bare proxy URL (for example http://127.0.0.1:52347) is printed as the first and only line on stdout. Scripts and test harnesses can read that one line as their readiness signal.
Press Ctrl+C to stop the proxy. In-flight requests get a short grace period before their connections are closed.

Paths and scoping

By default the proxy is a pure passthrough of the platform API surface: the same paths that work against the real API endpoint work against the local port, including the scoped organization and project control-plane prefixes. Swapping one base URL gives a tool dev/prod parity with nothing else to change.
With an explicit --project or --organization flag, the proxy instead serves that single control plane at its root, so URLs lose the long control-plane prefix:
The session and scope are pinned when the proxy starts and shown in the banner. Switching your active account with datumctl auth switch or your context with datumctl ctx use does not affect a running proxy, and the proxy never inherits a scope from your current context — scoping is always an explicit flag. Restart the proxy to pick up a new session or scope.

Streaming

Streaming responses — watch requests, server-sent events, chunked transfer — pass through unbuffered: each event reaches your client the moment the upstream sends it, and the proxy never limits how long a response stays open. This makes the proxy suitable for long-lived watch clients.

Credentials and token refresh

Every proxied request carries a fresh access token for the pinned session; the proxy refreshes the token before it expires and persists refreshed tokens exactly as other datumctl commands do. Service-account sessions work the same way. If the session cannot be refreshed — expired, revoked, or logged out with datumctl logout — the proxy stays up and answers requests with a synthesized 502 Bad Gateway carrying a JSON status body, an X-Datum-Proxy-Error: true marker header, and a message telling you to run datumctl login. The proxy recovers automatically, without a restart, once you log back in to the same session.
A 401 or 403 from the platform itself passes through unchanged and without the marker header, so your client can always tell a proxy-local authentication problem from a real platform answer.

Security model

  • Loopback only. The proxy listens on 127.0.0.1 and there is no flag to bind other addresses. Anything that should be reachable remotely deserves a tunnel whose security model you own.
  • Local clients are trusted. Like other local developer proxies, the proxy does not authenticate local clients: while it runs, any process on your machine can make API calls as the pinned session. The banner names the identity it serves, requests are logged by default, and the credential itself is never exposed — a local client can act through the proxy but cannot take your token with it.
  • Host-header validation. Requests whose Host is not localhost, 127.0.0.1, or [::1] are rejected with 403, which defeats DNS-rebinding attacks from web pages.
  • No CORS headers. Browsers refuse scripted cross-origin reads of proxy responses; the proxy is meant for server-side and command-line clients.
  • Authorization discipline. Any Authorization header your local client sends is stripped and replaced with the session’s real token, and tokens never appear in the request log.

Request logging

One line per request is written to stderr — silence it with --quiet:
Streaming responses log once when headers arrive (marked …streaming) and again when the stream ends, with total duration and bytes — so an abruptly closed watch is visible.
Last modified on July 17, 2026