> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ohmyho.st/llms.txt
> Use this file to discover all available pages before exploring further.

# 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.



## OpenAPI

````yaml /openapi.json post /v1/projects/{project_id}/deployments:plan
openapi: 3.1.2
info:
  title: ohmyho.st API
  version: 0.0.0
  description: >-
    Public REST API for ohmyho.st hosting, projects, domains, email, credits and
    exports.
servers:
  - url: https://app.ohmyho.st
    description: Production control API
  - url: https://dev.app.ohmyho.st
    description: Development control API
security:
  - BearerAuth: []
paths:
  /v1/projects/{project_id}/deployments:plan:
    post:
      summary: Plan a deployment
      description: >-
        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.
      operationId: planDeployment
      parameters:
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/ProjectId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlanDeploymentRequest'
      responses:
        '200':
          description: A deployment plan valid for fifteen minutes.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentPlan'
        '400':
          $ref: '#/components/responses/Problem'
        '401':
          $ref: '#/components/responses/Problem'
        '402':
          $ref: '#/components/responses/Problem'
        '403':
          $ref: '#/components/responses/Problem'
        '404':
          $ref: '#/components/responses/ResourceNotFound'
        '429':
          $ref: '#/components/responses/Problem'
        '503':
          $ref: '#/components/responses/Problem'
components:
  parameters:
    RequestId:
      name: X-Request-Id
      in: header
      description: Optional caller-provided correlation identifier.
      required: false
      schema:
        type: string
        minLength: 1
        maxLength: 128
    ProjectId:
      name: project_id
      in: path
      description: Project identifier.
      required: true
      schema:
        $ref: '#/components/schemas/Ulid'
  schemas:
    PlanDeploymentRequest:
      type: object
      additionalProperties: false
      required:
        - commit_sha
      properties:
        commit_sha:
          $ref: '#/components/schemas/GitCommitSha'
    DeploymentPlan:
      type: object
      description: >-
        Immutable pre-build deployment plan. It expires exactly fifteen minutes
        after creation.
      additionalProperties: false
      x-ohmyhost-ttl-seconds: 900
      required:
        - id
        - project_id
        - commit_sha
        - source_digest
        - build_plan_digest
        - application_root
        - runtime
        - route
        - resource_effects
        - limits
        - estimated_cost
        - risks
        - destructive_effects
        - required_confirmations
        - created_at
        - expires_at
      properties:
        id:
          $ref: '#/components/schemas/Ulid'
        project_id:
          $ref: '#/components/schemas/Ulid'
        commit_sha:
          $ref: '#/components/schemas/GitCommitSha'
        source_digest:
          $ref: '#/components/schemas/Sha256Digest'
        build_plan_digest:
          $ref: '#/components/schemas/Sha256Digest'
        application_root:
          type: string
          description: >-
            Canonical repository-relative application root selected from
            immutable source evidence.
          readOnly: true
          maxLength: 64
          pattern: >-
            ^(?:\.|[A-Za-z0-9][A-Za-z0-9._-]{0,62}(?:/[A-Za-z0-9][A-Za-z0-9._-]{0,62}){0,7})$
        artifact_digest:
          $ref: '#/components/schemas/Sha256Digest'
        runtime:
          type: string
          enum:
            - cloudflare_workers_static_assets
            - cloudflare_workers_edge_ssr
            - cloudflare_containers
        route:
          type: string
          description: >-
            Server-derived project-isolated public deployment URL; clients
            cannot select its gateway host or target Worker.
          format: uri
          pattern: ^https://
        resource_effects:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 512
        limits:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 512
        estimated_cost:
          $ref: '#/components/schemas/CostEstimate'
        risks:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 512
        destructive_effects:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 512
        required_confirmations:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 128
        created_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
    Ulid:
      type: string
      pattern: ^[0-9A-HJKMNP-TV-Z]{26}$
    GitCommitSha:
      type: string
      description: >-
        Exact full Git commit object identifier; abbreviated or branch
        references are forbidden.
      pattern: ^[0-9a-f]{40}$
    Sha256Digest:
      type: string
      pattern: ^sha256:[0-9a-f]{64}$
    CostEstimate:
      type: object
      description: >-
        Build-compute reservation quote, not the lifetime cost of the
        application. amount_micros is the customer USD equivalent of
        credit_micros; provider_cost_micros is the corresponding published
        provider-list basis. The versioned price is fixed by this immutable
        deployment plan. Actual measured usage settles the reservation and
        unused credits are released. Storage, mail and runtime costs are
        separate.
      additionalProperties: false
      required:
        - amount_micros
        - currency
        - rate_card_version
        - credit_micros
        - provider_cost_micros
        - scope
        - reserved_minutes
      properties:
        amount_micros:
          type: string
          pattern: ^[0-9]+$
        currency:
          type: string
          pattern: ^[A-Z]{3}$
        rate_card_version:
          type: string
          minLength: 1
          maxLength: 128
        credit_micros:
          type: string
          pattern: ^[0-9]+$
        provider_cost_micros:
          type: string
          pattern: ^[0-9]+$
        scope:
          type: string
          const: build_compute
        reserved_minutes:
          type: string
          pattern: ^[1-9][0-9]*$
    ProblemDetails:
      type: object
      description: RFC 9457 Problem Details extended with stable ohmyhost recovery fields.
      additionalProperties: false
      required:
        - type
        - title
        - status
        - code
        - request_id
        - retryable
        - suggested_action
      properties:
        type:
          type: string
          format: uri-reference
        title:
          type: string
          minLength: 1
        status:
          type: integer
          minimum: 400
          maximum: 599
        detail:
          type: string
        instance:
          type: string
          format: uri-reference
        code:
          type: string
          enum:
            - invalid_request
            - unauthenticated
            - forbidden
            - resource_not_found
            - idempotency_key_reused
            - project_handle_unavailable
            - project_identity_unavailable
            - deployment_plan_expired
            - deployment_plan_incompatible
            - confirmation_expired
            - confirmation_invalid
            - etag_mismatch
            - promotion_source_stale
            - promotion_target_stale
            - promotion_invalid_target
            - mail_domain_conflict
            - mail_domain_required
            - framework_conversion_required
            - migration_filename_noncanonical
            - environment_secret_mutation_blocked
            - container_runtime_required
            - payload_too_large
            - rate_limited
            - insufficient_organization_credits
            - paid_plan_required
            - project_budget_exceeded
            - compute_performance_paid_required
            - compute_performance_unavailable
            - compute_change_pending
            - compute_change_conflict
            - billing_purchase_conflict
            - cloudflare_authorization_closed
            - project_notes_conflict
            - project_export_not_ready
            - interactive_login_required
            - api_key_creation_uncertain
            - api_key_permissions_unavailable
            - reconciliation_exhausted
            - service_unavailable
        request_id:
          type: string
          minLength: 1
          maxLength: 128
        retryable:
          type: boolean
        retry_after_seconds:
          type: integer
          minimum: 1
          maximum: 86400
          description: >-
            Optional machine-readable retry delay for a rate limit, matching
            Retry-After.
        suggested_action:
          type: string
          minLength: 1
  headers:
    XRequestId:
      description: Correlates the request with operations, events, logs, and audit records.
      required: true
      schema:
        type: string
        minLength: 1
        maxLength: 128
  responses:
    Problem:
      description: The request failed.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/XRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetails'
    ResourceNotFound:
      description: >-
        The resource does not exist or is not visible to the authenticated
        principal.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/XRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetails'
          examples:
            resourceNotFound:
              value:
                type: https://docs.ohmyho.st/errors/resource-not-found
                title: Resource not found
                status: 404
                code: resource_not_found
                request_id: req_01J00000000000000000000000
                retryable: false
                suggested_action: Check the resource identifier and your access scope.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        WorkOS access JWT or a user-owned WorkOS API key. User keys are bound to
        one organization and restricted to their enabled product permissions.
        Session-only onboarding and session revocation require an interactive
        access JWT. No cookie session is assumed.

````