{
  "openapi": "3.1.1",
  "info": {
    "title": "CapVM",
    "description": "CapVM API. Base URL: https://api.capvm.com/v1. Prepaid ARM and GPU machines for AI agents. Money is integer micro-USD. Authorize with Bearer ak_live_ or ak_test_. Admin routes use a separate token. MCP is not part of this document. Connect a streamable HTTP client to https://api.capvm.com/mcp with the same Bearer ak_ key.",
    "version": "v1"
  },
  "paths": {
    "/v1/checkout/sessions": {
      "post": {
        "tags": [
          "Checkout"
        ],
        "summary": "Create a Stripe Checkout Session for a prepaid top-up. Requires Idempotency-Key and a Bearer ak_ key. A missing or empty key is 400 idempotency_key_required. REST says \"Idempotency-Key header is required.\" MCP says \"idempotency_key is required.\" Leading and trailing whitespace is trimmed, and the stored key is that trimmed value. Length is the trimmed value's UTF-16 code unit count, the same count as String.Length, not Unicode scalar values and not UTF-8 bytes, and must be 1 to 255. A whitespace-only key, a trimmed length outside 1 to 255, or a control character (Char.IsControl) is 400 idempotency_key_invalid. REST says \"Idempotency-Key must be 1 to 255 characters after trimming, with no control characters.\" MCP says \"idempotency_key must be 1 to 255 characters after trimming, with no control characters.\" Over REST, a whitespace-only Idempotency-Key header counts as empty and is idempotency_key_required. An MCP argument is not stripped, so a whitespace-only idempotency_key stays idempotency_key_invalid. Two Idempotency-Key header values are idempotency_key_invalid. An absent header, or a header with no values, is idempotency_key_required. amount_usd is a whole number of dollars or a string with at most two decimal places. Minimum $10. Maximum is Stripe:MaximumAmountCents (default $1000). Prices exclude VAT. Stripe Tax adds tax unless Stripe:TaxMode is manual. Company name is required. VAT ID is optional. Billing address is required. The invoice description is CapVM prepaid compute credits. 403 terms_not_accepted, with required_versions and accept_url, until the current Terms and AUP are accepted. There is no refunds route. Credits are non-refundable during the beta.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/CreateCheckoutSessionRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutSessionResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TermsNotAcceptedResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stripe/webhook": {
      "post": {
        "tags": [
          "Stripe"
        ],
        "summary": "Stripe webhook. No API key. Verifies Stripe-Signature with Stripe:WebhookSecret. Handles checkout.session.completed and checkout.session.async_payment_succeeded when payment_status is paid, using amount_subtotal so tax is not credited. The same Checkout Session id credits once. Also handles charge.refunded, charge.refund.updated, refund.updated, charge.dispute.created, charge.dispute.updated, charge.dispute.closed, and charge.dispute.funds_reinstated. Dispute credits are removed when the dispute opens and restored if we win. Inquiries are logged only. Refunds remove the pre-tax credits. The webhook marks the organization and does not stop machines inline. Unknown events return 200. There is no refunds route. Credits are non-refundable during the beta.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StripeWebhookResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/waitlist": {
      "post": {
        "tags": [
          "Waitlist"
        ],
        "summary": "Join the public waitlist. Deduped by email.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/WaitlistRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WaitlistResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/signup": {
      "post": {
        "tags": [
          "Signup"
        ],
        "summary": "Start signup. Creates the organization in pending_acceptance and emails a human a single-use acceptance link. A failed send voids that link and returns 503 email_send_failed. An agent cannot accept.",
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignupResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/machines": {
      "post": {
        "tags": [
          "Machines"
        ],
        "summary": "Create a machine. Requires Idempotency-Key. A missing or empty key is 400 idempotency_key_required. REST says \"Idempotency-Key header is required.\" MCP says \"idempotency_key is required.\" Leading and trailing whitespace is trimmed, and the stored key is that trimmed value. Length is the trimmed value's UTF-16 code unit count, the same count as String.Length, not Unicode scalar values and not UTF-8 bytes, and must be 1 to 255. A whitespace-only key, a trimmed length outside 1 to 255, or a control character (Char.IsControl) is 400 idempotency_key_invalid. REST says \"Idempotency-Key must be 1 to 255 characters after trimming, with no control characters.\" MCP says \"idempotency_key must be 1 to 255 characters after trimming, with no control characters.\" Over REST, a whitespace-only Idempotency-Key header counts as empty and is idempotency_key_required. An MCP argument is not stripped, so a whitespace-only idempotency_key stays idempotency_key_invalid. Two Idempotency-Key header values are idempotency_key_invalid. An absent header, or a header with no values, is idempotency_key_required. Holds price times ttl_seconds. 403 terms_not_accepted until the organization has accepted the current Terms and AUP.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/CreateMachineRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineResponse"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TermsNotAcceptedResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Machines"
        ],
        "summary": "List machines for the calling API key.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/machines/{id}": {
      "get": {
        "tags": [
          "Machines"
        ],
        "summary": "Get one machine for the calling API key.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Machines"
        ],
        "summary": "Stop a machine, charge billed seconds, and release the rest of the hold.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/machines/{id}/exec": {
      "post": {
        "tags": [
          "Machines"
        ],
        "summary": "Run a shell command on a ready machine owned by this key. Returns stdout, stderr, exit code, and whether output was truncated.",
        "description": "408 command_timeout when a command that has started exceeds timeout_seconds, including when a post-cancel GetCommandInvocation is Cancelled and ExecutionStartDateTime is set. 409 machine_not_ready when the SSM agent PingStatus is not Online, or when CancelCommand at the 30 second pickup deadline is followed, after any Pending or Cancelling polls, by status Cancelled with an empty ExecutionStartDateTime. A command that provably never started is never command_timeout. Both of those agent machine_not_ready results write command_audits with outcome not_ready. 409 machine_not_ready with \"Machine is not ready yet.\" when the lease is not in the ready state writes no command_audits row, because no AWS call was made. 500 internal_error when the command finished but the audit record could not be stored. 502 provider_error when the compute provider fails, including when DescribeInstanceInformation fails, and when a terminal Success or Failed invocation has no ResponseCode (\"The machine did not report an exit code.\"). The exec/ output objects are still deleted.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/ExecRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExecResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "408": {
            "description": "Request Timeout",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Bad Gateway",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/account": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Organization account for the signed-in human or the calling ak_ key.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/balance": {
      "get": {
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalanceResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/org/keys": {
      "get": {
        "tags": [
          "Organization"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgKeyListResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Organization"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/CreateOrgKeyRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedOrgKeyResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/org/keys/{id}": {
      "get": {
        "tags": [
          "Organization"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgKeyResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Organization"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/PatchOrgKeyRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgKeyResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Organization"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokedKeyResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/org/machines": {
      "get": {
        "tags": [
          "Organization"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/org/machines/{id}": {
      "delete": {
        "tags": [
          "Organization"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/org/usage": {
      "get": {
        "tags": [
          "Organization"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/orgs": {
      "post": {
        "tags": [
          "Admin"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/CreateOrgRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrgResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/orgs/{orgId}/keys": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Issue an API key. 403 terms_not_accepted, with required_versions and accept_url, until the organization has accepted the current Terms and AUP.",
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/IssueKeyRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssuedKeyResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TermsNotAcceptedResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/orgs/{orgId}/acceptance-links": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Email a single-use acceptance link. Stores the notice version the page will show. signup-checkbox-0.2 for a first acceptance, reaccept-checkbox-0.2 only after an earlier acceptance. A new link voids older unused links for the organization. 409 acceptance_current sends nothing when acceptance is already current. A failed send voids the new link and returns 503 email_send_failed. The token is only in the email.",
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/AcceptanceLinkRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptanceLinkResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/keys/{keyId}/revoke": {
      "post": {
        "tags": [
          "Admin"
        ],
        "parameters": [
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokedKeyResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/orgs/{orgId}/credits": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Append a topup ledger entry of at least $10. Idempotent by idempotency_key or stripe_event_id. A stripe_event_id marks the org trusted. 403 terms_not_accepted, with required_versions and accept_url, until acceptance is current.",
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/AddCreditsRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditsResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TermsNotAcceptedResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/orgs/{orgId}/freeze": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Freeze an organization. Writes a security event. Sign-in still works. Creating keys, raising caps, renaming keys, creating machines, and top-ups return org_frozen. Stopping a machine and lowering a cap still work.",
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FrozenOrgResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/orgs/{orgId}/unfreeze": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Clear orgs.frozen_at. Admin only. Writes a security event.",
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FrozenOrgResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/admin/orgs/{orgId}/trusted": {
      "post": {
        "tags": [
          "Admin"
        ],
        "summary": "Set orgs.trusted. True lifts the new-account concurrency caps.",
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/SetTrustedRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrustedOrgResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AcceptanceLinkRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": [
              "null",
              "string"
            ]
          },
          "country": {
            "type": [
              "null",
              "string"
            ]
          },
          "vat_id": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "AcceptanceLinkResponse": {
        "required": [
          "org_id",
          "user_id",
          "status",
          "request_id",
          "expires_at",
          "notice_version"
        ],
        "type": "object",
        "properties": {
          "org_id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "notice_version": {
            "type": "string"
          }
        }
      },
      "AccountResponse": {
        "required": [
          "org_id",
          "company_name",
          "status",
          "balance_micro",
          "frozen"
        ],
        "type": "object",
        "properties": {
          "org_id": {
            "type": "string",
            "format": "uuid"
          },
          "company_name": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "balance_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "frozen": {
            "type": "boolean"
          }
        }
      },
      "AddCreditsRequest": {
        "type": "object",
        "properties": {
          "amount_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "idempotency_key": {
            "type": [
              "null",
              "string"
            ]
          },
          "stripe_event_id": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "ApiKeyMode": {
        "enum": [
          "test",
          "live"
        ]
      },
      "BalanceResponse": {
        "required": [
          "available_micro",
          "held_micro",
          "currency",
          "unit"
        ],
        "type": "object",
        "properties": {
          "available_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "held_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "currency": {
            "type": "string"
          },
          "unit": {
            "type": "string"
          }
        }
      },
      "CheckoutSessionResponse": {
        "required": [
          "id",
          "url"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        }
      },
      "CreateCheckoutSessionRequest": {
        "type": "object",
        "properties": {
          "amount_usd": {
            "oneOf": [
              {
                "pattern": "^\\d+(\\.\\d{1,2})?$",
                "type": "string"
              },
              {
                "minimum": 10,
                "type": "integer"
              }
            ],
            "description": "USD amount. A JSON integer is a whole number of dollars. A string may include cents, with at most two decimal places. Minimum 10. Floats are rejected."
          },
          "success_url": {
            "type": [
              "null",
              "string"
            ]
          },
          "cancel_url": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "CreatedOrgKeyResponse": {
        "required": [
          "id",
          "secret",
          "label",
          "prefix",
          "spend_cap_micro",
          "created_at"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "secret": {
            "type": "string"
          },
          "label": {
            "type": [
              "null",
              "string"
            ]
          },
          "prefix": {
            "type": "string"
          },
          "spend_cap_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateMachineRequest": {
        "type": "object",
        "properties": {
          "sku": {
            "type": [
              "null",
              "string"
            ]
          },
          "ttl_seconds": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          }
        }
      },
      "CreateOrgKeyRequest": {
        "type": "object",
        "properties": {
          "label": {
            "type": [
              "null",
              "string"
            ]
          },
          "spend_cap_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int64"
          }
        }
      },
      "CreateOrgRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "CreditsResponse": {
        "required": [
          "balance_micro",
          "ledger_entry_id",
          "replayed"
        ],
        "type": "object",
        "properties": {
          "balance_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "ledger_entry_id": {
            "type": "string",
            "format": "uuid"
          },
          "replayed": {
            "type": "boolean"
          }
        }
      },
      "ErrorDetail": {
        "required": [
          "code",
          "message"
        ],
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "ErrorResponse": {
        "required": [
          "error"
        ],
        "type": "object",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        }
      },
      "ExecRequest": {
        "type": "object",
        "properties": {
          "command": {
            "type": [
              "null",
              "string"
            ]
          },
          "timeout_seconds": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "working_directory": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "ExecResponse": {
        "required": [
          "stdout",
          "stderr",
          "exit_code",
          "truncated"
        ],
        "type": "object",
        "properties": {
          "stdout": {
            "type": "string"
          },
          "stderr": {
            "type": "string"
          },
          "exit_code": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "truncated": {
            "type": "boolean"
          }
        }
      },
      "FrozenOrgResponse": {
        "required": [
          "id",
          "frozen_at",
          "frozen"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "frozen_at": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "frozen": {
            "type": "boolean"
          }
        }
      },
      "IssuedKeyResponse": {
        "required": [
          "id",
          "secret",
          "hint",
          "mode",
          "spend_cap_micro",
          "max_concurrent_machines",
          "allowed_skus",
          "created_at",
          "tos_version",
          "aup_version"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "secret": {
            "type": "string"
          },
          "hint": {
            "type": "string"
          },
          "mode": {
            "$ref": "#/components/schemas/ApiKeyMode"
          },
          "spend_cap_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "max_concurrent_machines": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "allowed_skus": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "tos_version": {
            "type": [
              "null",
              "string"
            ]
          },
          "aup_version": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "IssueKeyRequest": {
        "type": "object",
        "properties": {
          "mode": {
            "type": [
              "null",
              "string"
            ]
          },
          "spend_cap_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "max_concurrent_machines": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "allowed_skus": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          }
        }
      },
      "MachineListResponse": {
        "required": [
          "machines"
        ],
        "type": "object",
        "properties": {
          "machines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MachineResponse"
            }
          }
        }
      },
      "MachineResponse": {
        "required": [
          "id",
          "sku",
          "state",
          "instance_id",
          "public_ip",
          "region",
          "instance_type",
          "ttl_seconds",
          "price_per_hour_micro",
          "hold_micro",
          "charge_micro",
          "created_at",
          "expires_at",
          "ready_at",
          "stop_requested_at",
          "terminated_at"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "sku": {
            "type": "string"
          },
          "state": {
            "$ref": "#/components/schemas/MachineState"
          },
          "instance_id": {
            "type": [
              "null",
              "string"
            ]
          },
          "public_ip": {
            "type": [
              "null",
              "string"
            ]
          },
          "region": {
            "type": "string"
          },
          "instance_type": {
            "type": "string"
          },
          "ttl_seconds": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "price_per_hour_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "hold_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "charge_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "ready_at": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "stop_requested_at": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "terminated_at": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "MachineState": {
        "enum": [
          "requested",
          "provisioning",
          "ready",
          "stopping",
          "terminated"
        ]
      },
      "OrgKeyListResponse": {
        "required": [
          "keys"
        ],
        "type": "object",
        "properties": {
          "keys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrgKeyResponse"
            }
          }
        }
      },
      "OrgKeyResponse": {
        "required": [
          "id",
          "label",
          "prefix",
          "created_at",
          "created_ip",
          "last_used_at",
          "revoked_at",
          "spend_cap_micro"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": [
              "null",
              "string"
            ]
          },
          "prefix": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_ip": {
            "type": [
              "null",
              "string"
            ]
          },
          "last_used_at": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "revoked_at": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "spend_cap_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          }
        }
      },
      "OrgResponse": {
        "required": [
          "id",
          "name",
          "balance_micro",
          "created_at"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "balance_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PatchOrgKeyRequest": {
        "type": "object",
        "properties": {
          "label": {
            "type": [
              "null",
              "string"
            ]
          },
          "spend_cap_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int64"
          }
        }
      },
      "RequiredVersions": {
        "required": [
          "tos_version",
          "aup_version"
        ],
        "type": "object",
        "properties": {
          "tos_version": {
            "type": "string"
          },
          "aup_version": {
            "type": "string"
          }
        }
      },
      "RevokedKeyResponse": {
        "required": [
          "id",
          "revoked_at"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "revoked_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SetTrustedRequest": {
        "type": "object",
        "properties": {
          "trusted": {
            "type": [
              "null",
              "boolean"
            ]
          }
        }
      },
      "SignupResponse": {
        "required": [
          "org_id",
          "user_id",
          "status",
          "request_id",
          "expires_at"
        ],
        "type": "object",
        "properties": {
          "org_id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "StripeWebhookResponse": {
        "required": [
          "received",
          "credited",
          "replayed"
        ],
        "type": "object",
        "properties": {
          "received": {
            "type": "boolean"
          },
          "credited": {
            "type": "boolean"
          },
          "replayed": {
            "type": "boolean"
          }
        }
      },
      "TermsNotAcceptedError": {
        "required": [
          "code",
          "message",
          "required_versions",
          "accept_url"
        ],
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "required_versions": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/RequiredVersions"
              }
            ]
          },
          "accept_url": {
            "type": "string"
          }
        }
      },
      "TermsNotAcceptedResponse": {
        "required": [
          "error"
        ],
        "type": "object",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/TermsNotAcceptedError"
          }
        }
      },
      "TrustedOrgResponse": {
        "required": [
          "id",
          "trusted"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "trusted": {
            "type": "boolean"
          }
        }
      },
      "UsageEventResponse": {
        "required": [
          "id",
          "machine_id",
          "sku",
          "seconds",
          "amount_micro",
          "created_at"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "machine_id": {
            "type": "string"
          },
          "sku": {
            "type": "string"
          },
          "seconds": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "amount_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "UsageResponse": {
        "required": [
          "spend_micro",
          "held_micro",
          "spend_cap_micro",
          "events"
        ],
        "type": "object",
        "properties": {
          "spend_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "held_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "spend_cap_micro": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UsageEventResponse"
            }
          }
        }
      },
      "WaitlistRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": [
              "null",
              "string"
            ]
          },
          "source": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "WaitlistResponse": {
        "required": [
          "email",
          "created"
        ],
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "created": {
            "type": "boolean"
          }
        }
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "description": "Agent routes take an ak_ key. Admin routes take the admin token from the environment.",
        "scheme": "bearer",
        "bearerFormat": "ak_live_ or ak_test_ key, or the admin token on /v1/admin"
      }
    }
  },
  "tags": [
    {
      "name": "Checkout"
    },
    {
      "name": "Stripe"
    },
    {
      "name": "Waitlist"
    },
    {
      "name": "Signup"
    },
    {
      "name": "Machines"
    },
    {
      "name": "Account"
    },
    {
      "name": "Organization"
    },
    {
      "name": "Admin"
    }
  ]
}