{
  "openapi": "3.1.0",
  "info": {
    "title": "x402vps — Docker containers for AI agents",
    "version": "1.0.0",
    "description": "Provision Docker containers on demand. Pay per lease hour with USDC on Base. No signup, no API key — your wallet is your identity. Built for AI agents using the x402 protocol.",
    "x-guidance": "x402vps lets agents provision Docker containers and run commands inside them. Use POST /api/create to provision a container (pick plan + lease hours), POST /api/exec {id, command} to run commands inside a running container (free, rate-limited), POST /api/extend {id, hours} to extend the lease, POST /api/destroy {id} to tear it down (free), GET /api/list to list your containers, and GET /api/status/:id to check a container's status. Authentication is via X-Wallet header (your EVM wallet address). Payment is in USDC on Base via the x402 protocol — set up an agentcash wallet and the middleware handles it automatically.",
    "contact": {
      "email": "amir@x402vps.com"
    }
  },
  "servers": [
    {
      "url": "https://x402vps.com",
      "description": "Production server (Base mainnet)"
    }
  ],
  "paths": {
    "/api/create": {
      "post": {
        "operationId": "createContainer",
        "summary": "Create a Docker container on demand",
        "description": "Provisions a Docker container with the specified plan, image, and lease duration. Price is dynamic based on plan × lease hours. Payment via x402 (USDC on Base).",
        "tags": ["Compute", "Containers"],
        "x-payment-info": {
          "price": {
            "mode": "dynamic",
            "currency": "USD",
            "min": "0.01",
            "max": "13.44"
          },
          "protocols": [
            { "x402": {} }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "plan": {
                    "type": "string",
                    "enum": ["atom", "cell", "node", "core"],
                    "default": "atom",
                    "description": "Compute plan: atom (0.1 vCPU, 256MB, $0.01/hr), cell (0.25 vCPU, 512MB, $0.02/hr), node (0.5 vCPU, 1GB, $0.04/hr), core (1 vCPU, 2GB, $0.08/hr)"
                  },
                  "image": {
                    "type": "string",
                    "default": "alpine:3.19",
                    "description": "Docker image to use (e.g., alpine:3.19, python:3.12-slim, node:22)"
                  },
                  "leaseHours": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 168,
                    "default": 1,
                    "description": "Number of hours to lease the container (1-168)"
                  }
                },
                "required": []
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Wallet",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[a-fA-F0-9]{40}$"
            },
            "description": "Your EVM wallet address (0x...). Also accepted as ?wallet= query param."
          }
        ],
        "responses": {
          "200": {
            "description": "Container created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "string", "example": "ctr_4cb194" },
                    "plan": { "type": "string", "example": "atom" },
                    "image": { "type": "string", "example": "alpine:3.19" },
                    "status": { "type": "string", "example": "running" },
                    "priceCharged": { "type": "string", "example": "$0.01" },
                    "leaseHours": { "type": "integer", "example": 1 },
                    "expiresAt": { "type": "integer", "example": 1784746373691 }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment Required — x402 challenge with USDC payment details"
          },
          "400": {
            "description": "Bad request — invalid plan, missing wallet, or bad parameters"
          },
          "401": {
            "description": "Wallet address required"
          },
          "429": {
            "description": "Rate limit exceeded (10 creates per hour)"
          }
        }
      }
    },
    "/api/extend": {
      "post": {
        "operationId": "extendLease",
        "summary": "Extend container lease",
        "description": "Extend the lease on an existing container by additional hours. Price = plan hourly rate × hours.",
        "tags": ["Compute", "Containers"],
        "x-payment-info": {
          "price": {
            "mode": "dynamic",
            "currency": "USD",
            "min": "0.01",
            "max": "13.44"
          },
          "protocols": [
            { "x402": {} }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^ctr_[a-f0-9]+$",
                    "description": "Container ID (e.g., ctr_4cb194)"
                  },
                  "hours": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 168,
                    "description": "Number of hours to extend the lease by"
                  }
                },
                "required": ["id", "hours"]
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Wallet",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[a-fA-F0-9]{40}$"
            },
            "description": "Your EVM wallet address"
          }
        ],
        "responses": {
          "200": {
            "description": "Lease extended successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "string" },
                    "expiresAt": { "type": "integer" },
                    "leaseHours": { "type": "integer" },
                    "priceCharged": { "type": "string" }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment Required — x402 challenge"
          },
          "403": {
            "description": "Access denied — container belongs to another wallet"
          },
          "404": {
            "description": "Container not found"
          }
        }
      }
    },
    "/api/destroy": {
      "post": {
        "operationId": "destroyContainer",
        "summary": "Destroy a container (FREE)",
        "description": "Destroys a running container and frees its resources. Free operation (no x402 payment required).",
        "tags": ["Compute", "Containers"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^ctr_[a-f0-9]+$",
                    "description": "Container ID to destroy"
                  }
                },
                "required": ["id"]
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Wallet",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[a-fA-F0-9]{40}$"
            },
            "description": "Your EVM wallet address"
          }
        ],
        "responses": {
          "200": {
            "description": "Container destroyed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "string" },
                    "destroyed": { "type": "boolean", "example": true }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Access denied"
          },
          "404": {
            "description": "Container not found"
          }
        }
      }
    },
    "/api/exec": {
      "post": {
        "operationId": "execCommand",
        "summary": "Execute command inside a container (FREE, rate-limited)",
        "description": "Run a command inside a running container you own. The exec operation is FREE (rate-limited to 60 commands per minute per wallet). No x402 payment required.",
        "tags": ["Compute", "Containers"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "pattern": "^ctr_[a-f0-9]+$",
                    "description": "Container ID"
                  },
                  "command": {
                    "type": "string",
                    "description": "Shell command to execute inside the container"
                  }
                },
                "required": ["id", "command"]
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-Wallet",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[a-fA-F0-9]{40}$"
            },
            "description": "Your EVM wallet address"
          }
        ],
        "responses": {
          "200": {
            "description": "Command executed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "stdout": { "type": "string" },
                    "stderr": { "type": "string" },
                    "exitCode": { "type": "integer" }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Access denied"
          },
          "404": {
            "description": "Container not found"
          },
          "429": {
            "description": "Rate limit exceeded (60 commands per minute)"
          }
        }
      }
    },
    "/api/list": {
      "get": {
        "operationId": "listContainers",
        "summary": "List your containers (FREE)",
        "description": "List all containers owned by your wallet. Free operation.",
        "tags": ["Compute", "Containers"],
        "parameters": [
          {
            "name": "wallet",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^0x[a-fA-F0-9]{40}$"
            },
            "description": "Your EVM wallet address (alternative to X-Wallet header)"
          }
        ],
        "responses": {
          "200": {
            "description": "List of containers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "wallet": { "type": "string" },
                    "count": { "type": "integer" },
                    "containers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "string" },
                          "plan": { "type": "string" },
                          "status": { "type": "string" },
                          "expiresAt": { "type": "integer" }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Wallet address required"
          }
        }
      }
    },
    "/api/status/{id}": {
      "get": {
        "operationId": "getContainerStatus",
        "summary": "Get container status (FREE)",
        "description": "Get detailed status of a container you own.",
        "tags": ["Compute", "Containers"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^ctr_[a-f0-9]+$"
            }
          },
          {
            "name": "X-Wallet",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[a-fA-F0-9]{40}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Container status"
          },
          "403": {
            "description": "Access denied"
          },
          "404": {
            "description": "Container not found"
          }
        }
      }
    },
    "/api": {
      "get": {
        "operationId": "getApiInfo",
        "summary": "API information (FREE)",
        "description": "Get API metadata, available plans, and endpoint documentation.",
        "tags": ["Info"],
        "responses": {
          "200": {
            "description": "API info with plans and endpoints"
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "healthCheck",
        "summary": "Health check (FREE)",
        "description": "Server health check endpoint.",
        "tags": ["Info"],
        "responses": {
          "200": {
            "description": "Server is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "example": "ok" },
                    "uptime": { "type": "number" },
                    "paymentEnabled": { "type": "boolean" }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "walletAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Wallet",
        "description": "Your EVM wallet address (0x...) for ownership verification. Pass as X-Wallet header or ?wallet= query parameter."
      }
    }
  },
  "security": [
    { "walletAuth": [] }
  ],
  "tags": [
    {
      "name": "Compute",
      "description": "Container compute operations — create, exec, extend, destroy"
    },
    {
      "name": "Containers",
      "description": "Container lifecycle management"
    },
    {
      "name": "Info",
      "description": "Server metadata and health"
    }
  ]
}
