Remotehost Docs

API Reference

The REST API behind the CLI and console

The rh CLI and the console are both clients of the same REST API — there's nothing they can do that this API doesn't expose. Base URL defaults to http://localhost:8787 in development (REMOTEHOST_API_URL for the CLI, NEXT_PUBLIC_API_URL for the console).

Authentication

Every /v1 request requires an Authorization: Bearer <token> header, using the same token rh login stores at ~/.config/remotehost/config.json. There is no separate API-key auth for /v1 today — org API keys (visible via GET /v1/orgs/:orgId/api-keys) exist as a concept but authenticate a different surface, not this REST API directly.

curl https://<api-host>/v1/me/orgs \
  -H "Authorization: Bearer $REMOTEHOST_TOKEN"

Health check

GET /health

Unauthenticated. Returns { "ok": true, "service": "remotehost-api" }.

Orgs

Method & pathDescription
GET /v1/me/orgsList orgs the caller belongs to
POST /v1/orgsCreate an org
GET /v1/orgs/:orgId/membersList org members
GET /v1/orgs/:orgId/subscriptionCurrent plan and status
PATCH /v1/orgs/:orgId/subscription/usage-guardrailsSet sandbox usage cap and overage policy
GET /v1/orgs/:orgId/usageMachine-hour usage against allowance and hard cap
GET /v1/orgs/:orgId/usage?projectId=:projectIdProject-scoped machine-hour usage against project cap
GET /v1/orgs/:orgId/activityOrg activity feed (lifecycle events)
GET /v1/orgs/:orgId/api-keysList org API keys
POST /v1/orgs/:orgId/billing/checkoutStart a Stripe checkout session for a plan

Usage guardrails

PATCH /v1/orgs/:orgId/subscription/usage-guardrails

Org admins can set a hard sandbox machine-hour cap and whether overage is allowed.

Request body
{
  "sandboxMachineHourLimit": 250,
  "sandboxOverageEnabled": false
}

For project-level blast-radius control, org admins can set a project cap:

PATCH /v1/orgs/:orgId/projects/:projectId/usage-guardrails
Request body
{
  "sandboxMachineHourLimit": 50
}

Set sandboxMachineHourLimit to null to remove the project cap. A project cap is enforced inside the org cap and uses the same billing period as the subscription. Add ?projectId=:projectId to the usage endpoint to return project-scoped usage and alert state.

Set sandboxMachineHourLimit to null to fall back to the catalog included allowance when overage is disabled. When overage is enabled and no explicit cap is set, usage may continue without a catalog cap for custom contracts.

The usage response exposes both the effective cap and the explicit override. sandboxMachineHourLimit is the cap enforced for the current period, while sandboxMachineHourLimitOverride is null when the subscription is using its default included allowance.

GET /v1/orgs/:orgId/usage
{
  "includedMachineHours": 200,
  "sandboxMachineHourLimit": 200,
  "sandboxMachineHourLimitOverride": null,
  "sandboxOverageEnabled": false,
  "usedMachineHours": 12.5,
  "remainingMachineHours": 187.5,
  "usageAlert": {
    "percentUsed": 6.25,
    "status": "normal",
    "message": "Sandbox machine-hour usage is within the current cap."
  }
}

Invitations

Method & pathDescription
GET /v1/orgs/:orgId/invitationsList pending invitations
POST /v1/orgs/:orgId/invitationsInvite a member by email
DELETE /v1/orgs/:orgId/invitations/:invitationIdRevoke a pending invitation
GET /v1/invitations/:tokenLook up an invitation by its token
POST /v1/invitations/:token/acceptAccept an invitation as the authenticated user

Projects

Method & pathDescription
GET /v1/orgs/:orgId/projectsList projects
POST /v1/orgs/:orgId/projectsCreate a project
PATCH /v1/orgs/:orgId/projects/:projectIdUpdate project metadata
PATCH /v1/orgs/:orgId/projects/:projectId/usage-guardrailsSet project sandbox cap

Sandboxes

Method & pathDescription
GET /v1/orgs/:orgId/sandboxesList sandboxes (excludes deleted)
POST /v1/orgs/:orgId/sandboxesCreate and provision a sandbox
POST /v1/sandboxes/:sandboxId/stopStop a running sandbox
POST /v1/sandboxes/:sandboxId/resizeSet an exact sandbox allocation
POST /v1/sandboxes/:sandboxId/metrics/sampleSample Firecracker sandbox CPU, memory, and disk pressure

Create a sandbox

POST /v1/orgs/:orgId/sandboxes
Request body
{
  "agent": "claude",
  "projectId": "proj_123",
  "name": "my-sandbox",
  "repository": "org/repo",
  "branch": "main",
  "profile": "auto",
  "sshPublicKey": "ssh-ed25519 AAAA... remotehost-cli"
}

agent and projectId are required (agent is "claude" or "codex") — every other field falls back to the project's defaults, a selected sandbox profile, or a server-generated value. profile can be "auto", "agent-small", "agent-standard", "build-heavy", "browser-heavy", "repo-large", or "long-running". If machineSize is also provided, it overrides the profile's initial machine tier. Without either field, profile is inferred from the requested machine size for backward compatibility. Region and infrastructure tier are chosen server-side from the org's plan and are not client inputs. Returns 201 with { "sandbox": { ... } }; the sandbox payload includes sandbox_profile so clients can display and meter the selected workload profile, plus allocated_vcpu, allocated_memory_gb, and allocated_disk_gb for the concrete resource shape. Returns 400 if projectId is missing or unknown, or 409 if the org is at its concurrent-sandbox limit.

List sandboxes

GET /v1/orgs/:orgId/sandboxes

Returns { "sandboxes": [...] }, newest first, excluding sandboxes with status: "deleted".

Stop a sandbox

POST /v1/sandboxes/:sandboxId/stop

Stops the sandbox and ends its machine-time billing.

Resize a sandbox

POST /v1/sandboxes/:sandboxId/resize
Request body
{
  "vcpu": 4,
  "memoryGb": 8,
  "diskGb": 80
}

Sets an exact allocation target. Stopped sandboxes update their persisted allocation immediately. Running sandboxes apply live only when the provider can verify the resource update; otherwise the requested shape is stored as pendingAllocation and used on the next resume.

Sample sandbox metrics

POST /v1/sandboxes/:sandboxId/metrics/sample

Samples CPU, memory, and disk pressure from a running Firecracker sandbox, records a sandbox_metrics_sample event, and returns the current allocation plus the recommended allocation. For auto sandboxes, a changed recommendation is stored as pendingAllocation and promoted the next time the sandbox is provisioned or resumed. Live in-place resize still requires an orchestrator resource-update primitive.

Errors

Error responses are { "error": { "message": "<message>" } } with a matching HTTP status code — 400 for invalid input, 401/403 for auth and membership failures, 402 for billing issues, 404 for missing resources, 409 for plan/limit conflicts, 429 for rate limits, 500 for provisioning or database failures.

On this page