Skip to content

Cloud API

The REST API exposed by Repster Cloud. Used by the Repster CLI and the Repster Cloud UI. You can call it directly for automation or integration.

Base URL: https://repster.online/api — the paths below are relative to it. (The browser UI is served at https://repster.online/; GET /health lives at the host root, outside /api.)

Auth: API key in the Authorization: Bearer rpk_... header. Keys are org-scoped, so all endpoints automatically scope to the calling key's org.

Client header: X-Repster-Client: <version>, sent automatically by the CLI.

Async runs: POST /runs returns a run_id immediately. Poll GET /runs/{id} or stream logs via GET /runs/{id}/logs?follow=true.

Auth endpoints (no token required)

Method Path Body Returns
POST /auth/register {email, password, org_slug, org_name} {org, api_key} (raw key shown once)
POST /auth/login {email, password, org_slug?} {org, api_key} (plus orgs: [...] when the user has multiple orgs) or {needs_org: true} when the user belongs to none
POST /auth/create-org {email, password, org_slug, org_name} {org, api_key}

When a user belongs to multiple orgs and org_slug is omitted from POST /auth/login, the response includes orgs listing all their orgs. Re-POST with org_slug to select one.

The login response also includes must_change_password: true when the account was created with a system-generated temporary password (operator provisioning or a member invite) and has not yet set its own. Password-authenticated surfaces require the reset first: the browser UI redirects to a change-password screen, and rp login walks the user through it.

User identity

Method Path Body Returns
GET /users/me {user_id, email, created_at}
GET /users/me/orgs [{org_id, slug, name, role, joined_at}]
POST /users/me/password {current_password, new_password} {org, api_key} — a fresh session key; clears the forced-reset flag and revokes other sessions

new_password must be at least 12 characters (422 otherwise); a wrong current_password returns 401.

Org management

Method Path Body Returns
GET /orgs/me {org_id, slug, name, created_at}
POST /orgs {slug, name} {org, api_key}

Key management (admin only)

Method Path Body Returns
POST /orgs/{org_id}/keys {name} {key_id, raw_key, ...} (raw key shown once)
GET /orgs/{org_id}/keys [{key_id, name, key_prefix, created_at, last_used_at, revoked_at}]
DELETE /orgs/{org_id}/keys/{key_id} {ok: true}

Member management (admin only)

Method Path Body Returns
GET /orgs/{org_id}/members [{user_id, email, role, created_at}]
POST /orgs/{org_id}/members {email, role?} {user_id, email, role, temp_password?} (201)
PATCH /orgs/{org_id}/members/{user_id} {role} updated member
DELETE /orgs/{org_id}/members/{user_id} {ok: true}

role defaults to "member". Valid values: "admin", "member". Cannot remove or demote the last admin (409). Cannot remove yourself (409).

Deployments

Method Path Body Returns
POST /deployments multipart: manifest + archive {deployment_id, code_digest}
GET /deployments?project= deployments for the caller's org, latest first

Creating a deployment (POST) is admin only; any org member can list them (GET). Deployments are immutable and content-addressed, so uploading the same archive twice returns the existing deployment.

Flows

Method Path Params Returns
GET /flows?project= optional project filter [{project, flow, schedule, entrypoint}] for the caller's org

The flows across the org's deployments, used by rp list --cloud and the UI Flows page. Available to any org member.

Runs

Method Path Body / Params Returns
POST /runs {project, flow, trigger, retry_of?} {run_id, status: "pending"} — the hosted service enqueues the run for the reconciler; it then progresses to running and a terminal state
GET /runs?project=&flow=&limit= run records for the caller's org
GET /runs/{id} {run_id, project, flow, status, trigger, deployment_id, started_at, finished_at, rows_loaded, summary, retry_of, duration_seconds, cost_usd, error}
GET /runs/{id}/logs ?follow=bool full log text; SSE stream when follow=true
POST /runs/{id}/cancel — (admin only) the updated run record with status: "cancelled"

POST /runs returns 404 with a helpful message if the flow has never been deployed. It also enforces spend guardrails before dispatch: 403 if the org is disabled (kill switch), 429 if the org has reached its monthly cost cap. A finished run records duration_seconds (wall-clock) and cost_usd (an estimate from the sandbox's pinned resources at Modal's published rates); both are null until the run finishes. A failed run also carries a short error reason (the full output stays in the run logs).

POST /runs/{id}/cancel terminates an in-flight run (Modal sandbox) and marks it cancelled. Returns 409 if the run has already finished (or is a local inline run with no detached handle), 404 if it isn't in the caller's org.

Usage

Method Path Returns
GET /usage {org_id, enabled, month, run_count, compute_seconds, cost_usd, monthly_cost_cap_usd, by_flow: [...]}

Current calendar-month (UTC) usage for the caller's org: run count, wall-clock compute seconds, estimated spend, and the effective monthly cost cap (null = unlimited). by_flow breaks the same figures down per (project, flow). Metering only — there is no billing.

Secrets (admin only)

Method Path Body Returns
PUT /projects/{project}/secrets {KEY: VALUE, ...} {ok: true}
GET /projects/{project}/secrets key names only (values are never returned)
DELETE /projects/{project}/secrets/{key} {ok: true}

Health

Method Path Returns
GET /health {ok: true} (no auth required)