ReferenceHTTP API

API

Authenticate external automation and operate routines through the versioned Hono API.

The service API is versioned under /v1. Browser sessions use Better Auth. External automation uses a bearer API key.

Authentication

curl https://api.workonrepeat.com/v1/routines \
  -H "Authorization: Bearer $WORK_ON_REPEAT_API_KEY"

An API key is bound to exactly one project. A session can select its active project with the X-Project-Id header, which takes precedence over the wor_project cookie; the API verifies membership either way.

Create a key

Create a key from Dashboard → API keys. Its plaintext form is shown once:

wor_<prefix>_<secret>

The database stores only a SHA-256 hash. Closing the one-time dialog removes the plaintext key from the UI state.

Scopes

ScopeGrants
models:readGET /v1/models
routines:readRead routines and their runs.
routines:writeCreate, update, archive, activate, pause.
runs:readList runs and read run detail.
runs:writeStart a manual run.
connections:readRead connections and tool policies.
connections:writeCreate connections, discover tools, set policies.

New keys default to models:read, routines:read, runs:read, and runs:write. Free and Starter permit read-only API requests; Pro and Scale permit writes. Browser sessions use membership and plan checks rather than API-key scopes.

Envelopes

Success
{ "data": {}, "requestId": "01J..." }
Error
{
  "error": { "code": "routine_not_found", "message": "…" },
  "requestId": "01J..."
}

Endpoints

Models

MethodPathScopeNotes
GET/v1/modelsmodels:readManaged LLMGateway options plus ready, enabled connected-account catalogs for the active project.

Each option carries the full reference provider, nullable connectionId, and modelId. A managed reference has provider llmgateway and a null connection; personal references require the exact owning connection. The catalog does not collapse two accounts that expose the same model ID.

Personal model connections

Listing uses the normal read scopes. Connect, reauthorize, and revoke require an authenticated browser session for the exact connection owner; an API key cannot act as that personal owner. Provider flags can make a descriptor visible while its connect action remains disabled.

MethodPathScopeNotes
GET/v1/model-connections/providersconnections:readFour provider descriptors, enablement, auth type, billing policy, and current session viewer.
GET/v1/model-connectionsconnections:readSafe account label, owner, status, validation time, fixed public error, and current model count.
GET/v1/model-connections/:connectionId/modelsmodels:readExact ready connection's current account catalog.
POST/v1/model-connections/:connectionId/revokeconnections:write + owner sessionRevokes credential use and returns the preserved audit record.
POST/v1/model-connections/openai-codex/device/startconnections:write + owner sessionStarts or replaces the owner's bounded ChatGPT device attempt.
GET/v1/model-connections/openai-codex/device/:attemptIdconnections:write + owner sessionPolls only the initiating owner's opaque attempt.
POST/v1/model-connections/openai-codex/device/:attemptId/cancelconnections:write + owner sessionCancels that device attempt.
POST/v1/model-connections/github-copilot/oauth/startconnections:write + owner sessionStarts dedicated Copilot OAuth; optional connectionId reauthorizes the same owned connection.
GET/v1/model-connections/github-copilot/oauth/callbackconnections:write + owner sessionCompletes the session-bound, single-use OAuth state.
GET/v1/model-connections/anthropic-agentconnections:readAnthropic API-key descriptor and enablement.
POST/v1/model-connections/anthropic-agent/api-keyconnections:write + owner sessionValidates a request-body-only key and creates or replaces the exact owned connection.

See Connect a model provider for product ownership, billing, status, and recovery semantics. Live-smoke diagnostics are default-off operator gates and are intentionally omitted from the normal integration surface.

Organizations and projects

Session-only. An API key receives 403 session_required.

MethodPathNotes
GET/v1/organizationsOrganizations you belong to.
POST/v1/organizationsCreates the organization and its default project.
GET/v1/projectsOptional ?organizationId= filter.
POST/v1/projectsRequires owner or admin in that organization.

Routines

MethodPathScopeNotes
GET/v1/routinesroutines:readAll routines in the project.
POST/v1/routinesroutines:write201. Returns webhookSecret once when a URL is set.
GET/v1/routines/:routineIdroutines:read
PATCH/v1/routines/:routineIdroutines:writeMaterial changes return the routine to draft.
DELETE/v1/routines/:routineIdroutines:writeArchives; history is retained.
POST/v1/routines/:routineId/runruns:write202. Enqueues a manual run.
POST/v1/routines/:routineId/activateroutines:write409 successful_run_required without a proof run.
POST/v1/routines/:routineId/pauseroutines:write
GET/v1/routines/:routineId/runsruns:readRuns for one routine.

Creating or updating a routine validates the schedule against the cron parser and the model against the live directory. Tool policies must reference a saved connection — inline tools return 400 tool_policy_requires_connection.

Runs

MethodPathScopeNotes
GET/v1/runsruns:readAll runs in the project.
GET/v1/runs/:runIdruns:readFull detail: steps, usage, webhook deliveries.

Connections and tool policies

MethodPathScopeNotes
GET/v1/connectionsconnections:readEncrypted material is never returned.
POST/v1/connectionsconnections:write201. Self-managed MCP server.
DELETE/v1/connections/:connectionIdconnections:writeDeletes stored credentials and the connection.
GET/v1/connections/providers—Managed providers and whether each is configured.
POST/v1/connections/oauth/:provider/start—Begins an OAuth authorization.
POST/v1/connections/api-key/:provider—Verifies and stores an API-key provider.
GET/v1/connections/:connectionId/accountsconnections:readLive provider accounts, e.g. Zernio.
POST/v1/routines/:routineId/connections/:connectionId/discoverconnections:writeCreates disabled tool policies.
GET/v1/routines/:routineId/toolsconnections:readTool policies for one routine.
PATCH/v1/routines/:routineId/tools/:policyIdconnections:writeRequires confirmAutomaticExecution: true to automate.

API keys

Session-only.

MethodPathNotes
GET/v1/api-keysNever returns hashes.
POST/v1/api-keys201. Returns key exactly once.
DELETE/v1/api-keys/:apiKeyIdRevokes.

Billing

Session-only. Billing mutations also require the active project's organization owner and an exact Origin matching UI_ORIGIN; bearer API keys cannot start Checkout or create customer-portal sessions.

MethodPathNotes
GET/v1/billingEffective plan, projected status, period, allowances, usage, and owner flag.
POST/v1/billing/checkoutBody: { "plan": "pro", "entrypoint": "pricing" }. Returns a Stripe URL.
POST/v1/billing/portalBody: {}. Returns a short-lived Stripe customer-portal URL.

The API chooses the Price, customer, and success/cancel URLs. Client-supplied Stripe IDs or redirect URLs are rejected. An already subscribed workspace is sent to the portal rather than creating a second subscription. Checkout's success redirect never grants access. Paid access changes only after a verified Stripe webhook or an authenticated server-side reconciliation against canonical Stripe subscription state.

See Billing for plan periods, cancellation, failed-payment grace, and the stable HTTP 402 contract.

Outside /v1

MethodPathNotes
GET/healthLiveness. Unauthenticated.
GET/oauth/callback/:providerThe UI forwards the provider's redirect here with the session cookie attached.
POST/internal/scheduler/tickX-Scheduler-Secret. For hosts driving the schedule externally. Returns 202.
POST/public/business-leadsTrusted UI origin, rate-limited Business enquiry. Returns 202.
POST/webhooks/stripeRaw signed Stripe lifecycle events. Never call from the browser.

Limits

Authenticated /v1 traffic is limited per credential in a fixed 60-second window. Responses include X-RateLimit-Limit and X-RateLimit-Remaining; a 429 also includes Retry-After. Request bodies are capped at 1 MB. Run execution is claimed from the durable SQLite queue and processed with bounded worker concurrency.

See Limits and quotas for every bound in one place, and Error codes for the complete list of failures.

On this page

Edit this page on GitHub