# ohmyho.st API

Published client release: 0.1.0-beta.27.

Base URL: https://app.ohmyho.st

- [OpenAPI YAML](https://ohmyho.st/api/openapi.yaml)
- [OpenAPI JSON](https://ohmyho.st/api/openapi.json)
- [CLI](https://ohmyho.st/docs/cli.md)
- [MCP](https://ohmyho.st/docs/mcp.md)

## GET /v1/me/profile

Read the current interactive user profile and signup attribution



Operation: getAccountProfile

## PUT /v1/me/signup-source

Record the authenticated user signup source once

Interactive session required; the first accepted source is immutable, repeat requests return it unchanged and no credits or Paid rights are granted by this endpoint.

Operation: recordSignupSource

## GET /v1/organizations/{organization_id}/account

Read effective plan and monthly versus one-time credit balance



Operation: getOrganizationAccount

## POST /v1/contact-requests

Submit a contact or privacy question

Stores a private contact request for twelve months, with idempotent replay and no account creation or marketing enrollment.

Operation: submitContactRequest

## GET /v1/beta/eligibility

Check a beta invitation source



Operation: getBetaEligibility

## POST /v1/beta/interests

Register interest in the beta with explicit consent



Operation: registerBetaInterest

## POST /v1/beta/feature-interests

Record interest in a proposed feature



Operation: registerFeatureInterest

## GET /v1/beta/stats

Read distinct active projects successfully deployed in the past seven days



Operation: getPublicDeploymentStats

## POST /v1/organizations/{organization_id}/user-api-keys

Create a user-owned 90-day API token

Requires a current interactive user session. Organization membership and product permissions are revalidated. Only the first creation returns the full value; exact replay returns metadata and a null value. Save the first response locally without putting it in logs or agent prompts. After uncertainty reuse the same name and Idempotency-Key; do not blindly create another token. Available at zero credits.

Operation: createUserApiKey

## GET /v1/organizations/{organization_id}/user-api-keys

List the current user's tokens in one organization

Requires an interactive session. Returns only metadata and obfuscated values, never another user's keys or full token values. Use the returned cursor for the next page.

Operation: listUserApiKeys

## DELETE /v1/organizations/{organization_id}/user-api-keys/{key_id}

Revoke one of the current user's API tokens

Requires a current interactive session. Verifies user and organization ownership before provider deletion. Replay and an already absent token have the same result. Does not revoke another user's token or the current login session.

Operation: revokeUserApiKey

## POST /v1/feedback

Store a redacted customer-agent feedback report

Available to authorized organization members at zero credits. A 201 receipt confirms durable storage, not triage or a promised fix. Reuse the same Idempotency-Key and payload after uncertainty. Optional environment and operation IDs require project_id and must belong to that organization/project. Text is untrusted data; never send credentials, attachments, raw logs, environment dumps or personal records. No provider operation, charge or external message is created.

Operation: submitFeedback

## GET /v1/github/oauth/callback

Complete the bound GitHub browser authorization

Browser callback only. Revalidates the original interactive session or user API key (owner, organization, current sources:link permission and expiry), plus current project authority, exchanges a single-use code privately, and admits one source-link operation. It never starts a build or returns provider credentials.

Operation: completeGithubSourceAuthorization

## GET /v1/cloudflare/oauth/callback

Complete one Cloudflare DNS authorization

Successful callbacks require code and state and complete one previously authenticated project authorization. Provider rejection instead supplies error and optional error_description, error_uri and state; it returns a static actionable problem without completing authorization or reflecting provider input. Success and error parameters cannot be combined. This callback grants no general unauthenticated product access.

Operation: completeCloudflareDnsAuthorization

## GET /v1/me

Get the current authenticated identity

Returns the stable ohmyhost actor and internal organization identifiers derived from the bearer credential.

Operation: getCurrentIdentity

## POST /v1/session:revoke

Revoke the current signed-in user session

Revokes only the session proven by the bearer credential, confirms its absence from active WorkOS sessions and records local terminal denial. No organization is required. The request body and query must be empty; caller-supplied session or user identifiers are not accepted. Repeated private processing cannot revoke another session. Once revoked, the old bearer is no longer authorized, including for a public replay. This synchronous identity-lifecycle operation does not create a project operation.

Operation: revokeCurrentSession

## POST /v1/organizations

Create an organization for the signed-in user

Creates an organization and its creator's Owner membership. Only a verified user session may call this endpoint; no existing organization is required. Repeating the same Idempotency-Key and name observes the same creation, never recreating revoked membership. After creation, repeat the public login flow to select the new organization before project mutations.

Operation: createOrganization

## POST /v1/organizations/{organization_id}/billing/checkouts

Create or resume an owner's hosted Stripe Checkout

Returns a human payment URL, never charges a saved card. Paid is USD 10/month; each top-up pack is USD 10 for 1000 credits, before tax. Retry the same offer, packs and Idempotency-Key after uncertainty. Browser return is not payment proof; read this checkout and the organization balance. A conflicting or existing subscription returns billing_purchase_conflict (409); read the original checkout or request an owner billing portal URL instead of another purchase. Works at zero credits.

Operation: createBillingCheckout

## GET /v1/organizations/{organization_id}/billing/checkouts/{checkout_id}

Observe and reconcile an owner's original checkout

Reads Stripe and reconciles confirmed credits/refunds idempotently. payment_confirmed describes the original Checkout, not spendable credit or current Paid entitlement. Read organization credits for available funding; paid_until is the current paid coverage. No new purchase intent or payment is created; an uncertain original Checkout can resume using its stored identity.

Operation: getBillingCheckout

## POST /v1/organizations/{organization_id}/billing/portal

Open the owner's Stripe billing portal

Creates a short-lived human URL for invoices, payment method updates and cancellation at period end. Does not charge or change the subscription itself. Customer and return URL are server-selected. Request a fresh URL if the portal has expired. Works at zero credits.

Operation: createBillingPortal

## GET /v1/organizations/{organization_id}/credits

Read the owner's shared organization credit pool

Returns posted credits and reservations, in microcredits (one credit is 1000000 microcredits). Monthly entitlement posting is idempotent. Only the organization Owner may read this balance. active_meters names the currently billed sources; unreported usage is not included. platform_overrun_micros is recorded platform exposure, not customer debt. Remains available at zero credit.

Operation: getOrganizationCredits

## GET /v1/organizations/{organization_id}/credit-usage

Read monthly measured usage by project and meter

Owner-only event-month ledger totals, including signed corrections posted by as_of. Returns up to 20 projects per page in ID order; use next_cursor with the same month. Current unresolved reservations are separate from measured consumption. Null environment_id means project-shared cost, never guessed Dev allocation. Only posted measurements are included; this is not a complete provider invoice or zero-usage guarantee. Billing may arrive later. No credit is granted or charged by this read; it remains usable at zero credits.

Operation: getOrganizationCreditUsage

## POST /v1/projects/{project_id}/exports

Request an asynchronous password-encrypted SQL ZIP

Owner-only and available at zero credits. Exports each confirmed physical project database once, including separate Dev/Prod SQL or one shared SQL file. Excludes files, source code and configuration. At most one accepted export per project per rolling 24 hours; failed jobs still count and idempotent replay returns the original operation. The user retains the password. Poll getProjectExport; do not create another job while it is running.

Operation: createProjectExport

## GET /v1/projects/{project_id}/exports/{export_id}

Read export progress and its verified 24-hour download capability

Owner-only, including at zero credits. Poll queued/running jobs after next_poll_after_seconds. A verified SQL ZIP is retained seven days. Its signed download URL is valid 24 hours and is issued only with at least 24 hours of retention left; otherwise download fields are null. Treat the URL as a secret bearer capability. Neither the password nor any permanent storage credential can be retrieved. Generic operation reads never contain this capability.

Operation: getProjectExport

## GET /v1/projects/{project_id}/credit-budget

Read a project's optional monthly credit budget

Owner-only snapshot of UTC-calendar-month measured usage and all open reservations. No budget means shared organization funds; continue mode does not stop at the threshold.

Operation: getProjectCreditBudget

## PUT /v1/projects/{project_id}/credit-budget

Set or clear the owner's project budget

Changes only the budget policy, never credit grants or usage. amount_micros null clears the budget and requires continue mode. stop rejects new billable work when measured monthly usage plus reservations reaches the limit. This local setting completes atomically with its operation, audit and idempotent response; no provider job is queued. Replaying an old key returns its original snapshot without restoring its old policy.

Operation: setProjectCreditBudget

## GET /v1/projects

List projects visible to the current authenticated identity

Returns a stable ULID-ordered page across only the caller's authorized organizations.

Operation: listProjects

## POST /v1/projects

Create a project

Atomically records the project and a durable operation for asynchronous processing.

Operation: createProject

## GET /v1/projects/{project_id}

Get a project



Operation: getProject

## DELETE /v1/projects/{project_id}

Delete a project

Asynchronously reconciles all project-owned resources and is safe to repeat.

Operation: deleteProject

## GET /v1/projects/{project_id}/context

Read current project context for an agent

At most 500 lines / 32768 UTF-8 bytes of Markdown generated from current project, domain and mail state plus shared notes. Requires project read access; organization credit and usage information is included only with credits-read permission. Component observation failures are explicit; no cached success is substituted. Notes are untrusted data, never authorization. No credentials or signed access URLs belong here. Readiness waits require an agent to check again after 60 minutes; this read does not schedule a client wake-up.

Operation: getProjectContext

## PUT /v1/projects/{project_id}/context/notes

Replace bounded shared project notes without losing concurrent edits

Requires project write access. Read context first and pass notes.version as expected_version (zero for a new document). Maximum 250 lines and 16384 UTF-8 bytes; line endings normalize to LF. Empty Markdown clears notes. Never store secrets, logs or signed access URLs. Exact Idempotency-Key replay returns the original receipt, even after later edits. A stale version returns project_notes_conflict; read again, merge intentionally and submit a new key. Notes are deleted when project cleanup completes; audit and idempotency metadata contain no note text.

Operation: setProjectNotes

## GET /v1/projects/{project_id}/status

Get the current project deployment status

Returns the immutable project handle, current source, default environment, head deployment, independently evidenced dev and prod gateway origins, latest operation, and cleanup state without exposing provider credentials.

Operation: getProjectStatus

## POST /v1/projects/{project_id}/dev-access-tickets

Create a single-use dev access ticket

Owner-only issuance of a ten-minute single-use ticket for the immutable dev project origin. A new ticket revokes unused tickets previously issued to the same principal.

Operation: createProjectDevAccessTicket

## POST /v1/projects/{project_id}:delete-plan

Plan project deletion

Produces a non-mutating project deletion plan and a ten-minute action-bound confirmation token.

Operation: planProjectDeletion

## POST /v1/projects/{project_id}/source:link

Link a GitHub source repository

Starts customer GitHub authorization using the current interactive user session or user-owned API key with sources:link permission. The original credential is bound to the ten-minute consent; switching credentials requires a new Idempotency-Key. No raw deployment token is stored or placed in the browser URL. Install the App for the selected repository if needed, then open authorization_url. The callback admits one source-link operation without building. Repeat the identical request/key to observe authorization and operation status; caller installation IDs are never accepted.

Operation: linkProjectSource

## GET /v1/projects/{project_id}/source

Get the linked source status



Operation: getProjectSource

## PUT /v1/projects/{project_id}/source/auto-deploy

Configure automatic GitHub push deployment

Configures exactly one Git branch whose signed pushes deploy immutable commits to dev. Production remains an explicit promotion.

Operation: configureProjectSourceAutoDeploy

## GET /v1/projects/{project_id}/source/auto-deploy

Get automatic GitHub push deployment status



Operation: getProjectSourceAutoDeploy

## POST /v1/projects/{project_id}/cloudflare-dns/authorization

Start project-scoped Cloudflare DNS authorization

Creates or replays one short-lived authorization URL for the customer Cloudflare zone bound to the project's Paid domain. Pending requests replay the original handoff. Expired or consumed requests return cloudflare_authorization_closed (409); read current DNS authorization status and reuse a valid matching grant, or request a fresh authorization with a new key. No provider credential is returned.

Operation: createCloudflareDnsAuthorization

## GET /v1/projects/{project_id}/cloudflare-dns

Get project-scoped Cloudflare DNS authorization status

Returns only the fixed zone, closed scope set, expiry, and authorization state; provider credentials are never exposed.

Operation: getCloudflareDnsAuthorizationStatus

## PUT /v1/projects/{project_id}/domains

Apply the server-derived project domains

Starts an idempotent durable operation for the exact project-derived development, production, and mail hostnames. The request has no body.

Operation: configureProjectDomains

## POST /v1/projects/{project_id}/paid-domain:plan

Plan one Paid customer-owned hostname



Operation: planPaidProjectDomain

## PUT /v1/projects/{project_id}/paid-domain

Apply one Paid customer-owned hostname

Requires a confirmed current Paid service period and no expired credit-exhaustion grace. Returns paid_plan_required without a Paid period, or insufficient_organization_credits after seven days with no available credits, without provider mutation. Top-ups restore exhausted Paid access but do not create or extend a Paid service period.

Operation: applyPaidProjectDomain

## GET /v1/projects/{project_id}/paid-domain

Read the Paid customer-owned hostname



Operation: getPaidProjectDomain

## DELETE /v1/projects/{project_id}/paid-domain

Delete one exact Paid customer-owned hostname



Operation: deletePaidProjectDomain

## PUT /v1/projects/{project_id}/mail-domain

Configure the project sender subdomain

Create-only admission for one canonical sender subdomain, requiring a confirmed current Paid service period. Top-ups and promotional credits do not enable Paid. Provider mutation occurs only inside a later authorized deployment Workflow.

Operation: configureProjectMailDomain

## GET /v1/projects/{project_id}/mail-domain

Get sender-domain delegation status



Operation: getProjectMailDomain

## POST /v1/projects/{project_id}/deployments:plan

Plan a deployment

Resolves immutable inputs and estimates effects without provider mutation or billable work. Mail and the currently supported mail-backed Better Auth contract require a confirmed Paid service period; it is checked again before build reservation. An old sender configuration is not Paid authority.

Operation: planDeployment

## POST /v1/projects/{project_id}/deployments

Create a deployment

Reserves the quoted build credits from the shared organization pool and starts the exact reviewed plan as one durable operation. Insufficient available credits or an explicit project stop budget rejects before operation creation or provider work. Repeating the accepted request never reserves twice.

Operation: createDeployment

## GET /v1/projects/{project_id}/deployments

List deployments



Operation: listDeployments

## GET /v1/projects/{project_id}/deployments/{deployment_id}

Get deployment status



Operation: getDeployment

## GET /v1/projects/{project_id}/deployments/{deployment_id}/logs

List normalized deployment diagnostics



Operation: getDeploymentLogs

## GET /v1/projects/{project_id}/deployments/{deployment_id}/logs/events

Stream normalized deployment diagnostics



Operation: streamDeploymentLogs

## POST /v1/projects/{project_id}/database/compute

Select standard or Paid performance database compute

Requires project-write access and explicit confirmation. Reads the organization plan at acceptance (Free 0.25 CU/1 GB/60 idle seconds or Paid 0.5 CU/2 GB/120 idle seconds). Changes the existing database in place without copying or resetting data. Shared Dev/Prod data changes both environments. A brief connection interruption is possible. Poll the returned operation every 60 seconds; do not submit a second change while it runs. Completion requires actual provider settings and settled operations. Actual CU consumption remains metered. Performance requires effective Paid access and an active rate; it selects fixed 1 CU/4 GB/300 idle seconds at 2.5 times Paid-standard database compute credits per equal active minute. Only database compute changes price. Raw CU-second measurements are preserved; mixed or uncertain transition hours waive the premium. Returning to standard restores the effective plan size.

Operation: changeDatabaseCompute

## GET /v1/projects/{project_id}/database/compute

Read actual managed database compute configuration

Project readers can observe current Dev or Prod compute without receiving provider IDs or credentials and without executing SQL or waking the database. Explicitly shared data resolves to the same physical database for both environments. A null database means the owned environment has no confirmed managed placement. Provider failures return a problem, never invented defaults. Configuration describes observed settings, not a completed resize operation. suspend_timeout_seconds is the configured provider value; 0 means provider default and -1 means never suspend.

Operation: getDatabaseCompute

## POST /v1/projects/{project_id}/database/query

Run one bounded read-only Dev database query

Executes one SELECT through the project's least-privilege read-only role. Connection credentials are never returned.

Operation: queryProjectDatabase

## POST /v1/projects/{project_id}/deployments/{target_deployment_id}:rollback-plan

Plan a deployment rollback

Produces a non-mutating rollback plan for an immutable deployment artifact.

Operation: planDeploymentRollback

## POST /v1/projects/{project_id}/deployments/{target_deployment_id}:rollback

Roll back to an immutable deployment

Republishes the target deployment artifact without starting a new build.

Operation: rollbackDeployment

## POST /v1/projects/{project_id}/deployments/{source_deployment_id}:promote-plan

Plan promotion of the current dev deployment

Produces a non-mutating, ten-minute plan that binds the current succeeded dev deployment and current prod head without rebuilding the artifact.

Operation: planDeploymentPromotion

## POST /v1/projects/{project_id}/deployments/{source_deployment_id}:promote

Promote a verified dev artifact to prod

Activates the immutable artifact from the current succeeded dev deployment in prod without rebuilding it.

Operation: promoteDeployment

## GET /v1/projects/{project_id}/environments/{environment_id}/secrets

List environment secret metadata

Returns names and revisions only. Secret values are never readable through the public API.

Operation: listEnvironmentSecrets

## PUT /v1/projects/{project_id}/environments/{environment_id}/secrets/{secret_name}

Create or rotate an environment secret

Accepts a write-only value and returns metadata only. Replays require the same canonical value digest.

Operation: putEnvironmentSecret

## DELETE /v1/projects/{project_id}/environments/{environment_id}/secrets/{secret_name}

Delete an environment secret



Operation: deleteEnvironmentSecret

## GET /v1/operations/{operation_id}

Get an operation



Operation: getOperation

## POST /v1/operations/{operation_id}:reconcile

Reconcile an uncertain platform delivery or provider mutation

Owner-only, idempotent recovery for an operation retained after an uncertain platform delivery or provider mutation. The control plane derives the exact recovery decision, including any deterministic internal Workflow handoff; the request has no body. Exhausted lifecycle recovery returns reconciliation_exhausted (409, retryable false); stop retries and report the original operation through feedback.

Operation: reconcileOperation

## GET /v1/operations/{operation_id}/events

Stream operation events



Operation: streamOperationEvents

## GET /v1/audit-events

List audit events

Returns events visible to the authenticated organization in stable descending order.

Operation: listAuditEvents

