{
  "openapi": "3.1.0",
  "info": {
    "title": "ToolRouter API",
    "description": "ToolRouter REST API for discovering and calling AI tools. Stable endpoints use the /v1 path; lifecycle policy: https://toolrouter.com/docs/api-lifecycle.",
    "version": "1.0.0",
    "contact": {
      "url": "https://toolrouter.com/docs/api-reference"
    }
  },
  "servers": [
    {
      "url": "https://api.toolrouter.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "x-service-info": {
    "categories": [
      "ai-tools",
      "developer-api",
      "pay-per-use"
    ]
  },
  "externalDocs": {
    "description": "ToolRouter REST API reference and lifecycle policy",
    "url": "https://toolrouter.com/docs/api-reference"
  },
  "x-api-lifecycle": {
    "versioning": "URL path",
    "currentVersion": "v1",
    "policy": "https://toolrouter.com/docs/api-lifecycle",
    "deprecationHeader": "Deprecation",
    "sunsetHeader": "Sunset"
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key from toolrouter.com/dashboard/api-keys"
      }
    },
    "schemas": {
      "Tool": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "subtitle": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "version": {
            "type": "string"
          },
          "skills": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Skill"
            }
          }
        }
      },
      "Skill": {
        "type": "object",
        "required": [
          "name",
          "displayName",
          "description"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "input": {
            "type": "object",
            "additionalProperties": true
          },
          "outputSchema": {
            "type": "object",
            "additionalProperties": true
          },
          "returns": {
            "type": "string"
          },
          "examples": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        },
        "additionalProperties": true
      },
      "ToolList": {
        "type": "object",
        "required": [
          "tools"
        ],
        "properties": {
          "tools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tool"
            }
          }
        }
      },
      "SkillsResponse": {
        "type": "object",
        "required": [
          "tool",
          "displayName",
          "skills"
        ],
        "properties": {
          "tool": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "skills": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Skill"
            }
          }
        }
      },
      "ToolCallResult": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "id": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "success",
              "error",
              "pending"
            ]
          },
          "output": {
            "type": "object",
            "additionalProperties": true
          },
          "usage": {
            "type": "object",
            "additionalProperties": true
          },
          "meta": {
            "type": "object",
            "additionalProperties": true
          },
          "job_id": {
            "type": "string"
          },
          "poll_url": {
            "type": "string",
            "format": "uri"
          }
        },
        "additionalProperties": true
      },
      "BatchResponse": {
        "type": "object",
        "required": [
          "results"
        ],
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ToolCallResult"
            }
          }
        }
      },
      "Job": {
        "type": "object",
        "properties": {
          "jobId": {
            "type": "string"
          },
          "job_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "completed",
              "failed",
              "cancelled"
            ]
          },
          "result": {
            "type": "object"
          },
          "error": {
            "type": "string"
          },
          "logs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CancelResponse": {
        "type": "object",
        "required": [
          "cancelled",
          "job_id"
        ],
        "properties": {
          "cancelled": {
            "type": "boolean"
          },
          "job_id": {
            "type": "string"
          }
        }
      },
      "AssetMeta": {
        "type": "object",
        "required": [
          "asset_id",
          "content_type",
          "size_bytes",
          "created_at",
          "has_thumbnail"
        ],
        "properties": {
          "asset_id": {
            "type": "string"
          },
          "content_type": {
            "type": "string"
          },
          "size_bytes": {
            "type": "integer"
          },
          "tool": {
            "type": "string"
          },
          "skill": {
            "type": "string"
          },
          "created_at": {
            "type": [
              "string",
              "number"
            ]
          },
          "has_thumbnail": {
            "type": "boolean"
          }
        }
      },
      "BillingBalance": {
        "type": "object",
        "required": [
          "available_usd",
          "plan"
        ],
        "properties": {
          "available_usd": {
            "type": "number"
          },
          "plan": {
            "type": "string"
          },
          "accounts": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "top_up_hint": {
            "type": "string"
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "secret": {
            "type": "string",
            "writeOnly": true,
            "description": "Full key; returned only when created"
          },
          "key_prefix": {
            "type": "string"
          },
          "status": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "KeyList": {
        "type": "object",
        "required": [
          "keys"
        ],
        "properties": {
          "keys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiKey"
            }
          }
        }
      },
      "ProvisionResponse": {
        "type": "object",
        "required": [
          "api_key",
          "key_prefix",
          "claim_url",
          "account_id",
          "message"
        ],
        "properties": {
          "api_key": {
            "type": "string",
            "writeOnly": true
          },
          "key_prefix": {
            "type": "string"
          },
          "claim_url": {
            "type": "string",
            "format": "uri"
          },
          "account_id": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "onboarding": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "RequirementsResponse": {
        "type": "object",
        "required": [
          "requirements"
        ],
        "properties": {
          "requirements": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "name",
                "type"
              ],
              "properties": {
                "name": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "acquireUrl": {
                  "type": "string"
                },
                "setupGuide": {
                  "type": "string"
                },
                "registeredBy": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "status": {
            "type": "string",
            "const": "error"
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "auth",
                  "billing",
                  "rate_limit",
                  "validation",
                  "provider",
                  "not_found",
                  "server"
                ]
              },
              "resolution_hint": {
                "type": "string"
              },
              "retry_after": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        }
      },
      "MachineTopUpResult": {
        "type": "object",
        "description": "Returned once the payment settles and the credits are added.",
        "properties": {
          "credited_usd": {
            "type": "number",
            "description": "Credit value added to the account."
          },
          "charged_usd": {
            "type": "number",
            "description": "Amount actually paid, including the purchase fee."
          },
          "balance_usd": {
            "type": "number",
            "description": "Credit balance after the top-up."
          },
          "payment_ref": {
            "type": "string",
            "description": "Settled payment reference the grant is keyed on."
          }
        },
        "required": [
          "credited_usd",
          "charged_usd",
          "balance_usd",
          "payment_ref"
        ]
      }
    },
    "headers": {
      "RateLimitPolicy": {
        "description": "Named quota policy and request window",
        "schema": {
          "type": "string"
        }
      },
      "RateLimit": {
        "description": "Remaining quota and seconds until reset",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying a throttled request",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "Deprecation": {
        "description": "RFC 9745 structured deprecation date; present only on deprecated resources",
        "schema": {
          "type": "string"
        }
      },
      "Sunset": {
        "description": "RFC 8594 HTTP date after which a deprecated resource may stop responding",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "ErrorResponse": {
        "description": "Machine-readable ToolRouter error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimitError": {
        "description": "Request quota exceeded",
        "headers": {
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          },
          "RateLimit": {
            "$ref": "#/components/headers/RateLimit"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/v1/tools": {
      "get": {
        "summary": "List all tools",
        "operationId": "listTools",
        "security": [],
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tool catalog",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolList"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/tools/search": {
      "get": {
        "summary": "Search tools by natural language query",
        "operationId": "searchTools",
        "security": [],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Natural language search query"
          }
        ],
        "responses": {
          "200": {
            "description": "Matching tools",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolList"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/tools/{tool}": {
      "get": {
        "summary": "Get tool details including skill schemas",
        "operationId": "getTool",
        "security": [],
        "parameters": [
          {
            "name": "tool",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tool manifest with full skill schemas",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Tool"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/tools/{tool}/skills": {
      "get": {
        "summary": "List skills for a tool",
        "operationId": "getToolSkills",
        "security": [],
        "parameters": [
          {
            "name": "tool",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Skill objects with input/output schemas",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SkillsResponse"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/tools/call": {
      "post": {
        "summary": "Call a tool skill",
        "operationId": "callTool",
        "description": "Execute a tool skill. Long-running tools return a job_id — poll /v1/jobs/{jobId} until complete.",
        "x-payment-info": {
          "intent": "charge",
          "method": "stripe",
          "amount": "1",
          "currency": "usd",
          "pricing": "metered",
          "description": "Metered pay-per-use: a flat platform fee plus the underlying provider cost is deducted from the account's prepaid credit balance. Returns HTTP 402 when credits are insufficient."
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tool",
                  "skill",
                  "input"
                ],
                "properties": {
                  "tool": {
                    "type": "string",
                    "description": "Tool name, e.g. web-search"
                  },
                  "skill": {
                    "type": "string",
                    "description": "Skill name, e.g. search"
                  },
                  "input": {
                    "type": "object",
                    "description": "Skill input parameters"
                  },
                  "billing": {
                    "type": "string",
                    "description": "Account to bill: personal, team, or team slug"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Synchronous skill result",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolCallResult"
                }
              }
            }
          },
          "202": {
            "description": "Asynchronous job accepted",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolCallResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "402": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "403": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/tools/batch": {
      "post": {
        "summary": "Call multiple tools in parallel",
        "operationId": "batchCallTools",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "calls"
                ],
                "properties": {
                  "calls": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "tool",
                        "skill",
                        "input"
                      ],
                      "properties": {
                        "tool": {
                          "type": "string"
                        },
                        "skill": {
                          "type": "string"
                        },
                        "input": {
                          "type": "object"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Array of results in the same order as calls",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/jobs/{jobId}": {
      "get": {
        "summary": "Poll async job status",
        "operationId": "getJob",
        "description": "Returns immediately if complete. If still running, waits up to 30 seconds server-side before responding.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job status and result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "501": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/jobs/{jobId}/cancel": {
      "post": {
        "summary": "Cancel a running job",
        "operationId": "cancelJob",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "501": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/assets/{assetId}": {
      "get": {
        "summary": "Retrieve a generated asset",
        "operationId": "getAsset",
        "security": [],
        "description": "Returns the raw asset file (image, audio, document). No auth required — assets are accessed by opaque ID.",
        "parameters": [
          {
            "name": "assetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Asset file bytes",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/assets/{assetId}/meta": {
      "get": {
        "summary": "Get asset metadata",
        "operationId": "getAssetMeta",
        "security": [],
        "parameters": [
          {
            "name": "assetId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Asset metadata including content type, size, and creation time",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetMeta"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/billing/balance": {
      "get": {
        "summary": "Get credit balance",
        "operationId": "getBillingBalance",
        "responses": {
          "200": {
            "description": "Current credit balance in USD",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingBalance"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "403": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/keys": {
      "get": {
        "summary": "List API keys",
        "operationId": "listKeys",
        "responses": {
          "200": {
            "description": "API key objects with secrets masked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      },
      "post": {
        "summary": "Create API key",
        "operationId": "createKey",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Human-readable label"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "New API key (secret shown once)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKey"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "403": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/keys/{id}": {
      "delete": {
        "summary": "Delete API key",
        "operationId": "deleteKey",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Key deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "id"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "id": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/auth/provision": {
      "post": {
        "summary": "Provision a temporary API key",
        "operationId": "provisionKey",
        "security": [],
        "description": "Creates a provisional account and returns an API key. No auth required. Claim with /v1/auth/claim to attach to a real account.",
        "responses": {
          "201": {
            "description": "Provisional API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProvisionResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/requirements": {
      "get": {
        "summary": "List available provider requirements (API keys)",
        "operationId": "listRequirements",
        "security": [],
        "description": "Returns all configurable third-party API key slots — name, display name, and which tools need them.",
        "responses": {
          "200": {
            "description": "Provider requirement objects",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequirementsResponse"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    },
    "/v1/billing/machine-topup": {
      "post": {
        "summary": "Buy credits as an agent (machine payment)",
        "description": "Answers with a payment challenge in the WWW-Authenticate header. Pay it and retry the same request; the credits are added to the account the challenge was issued for, so the retry needs no API key.",
        "operationId": "machineTopUp",
        "x-payment-info": {
          "amount": "180",
          "currency": "usd",
          "description": "Credits requested plus the standard purchase fee; the charge scales with amount_usd."
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount_usd"
                ],
                "properties": {
                  "amount_usd": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 500,
                    "description": "Credit value to buy, in US dollars, no finer than whole cents."
                  }
                }
              },
              "example": {
                "amount_usd": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment accepted and credits added",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MachineTopUpResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponse"
          },
          "402": {
            "description": "Payment required — the challenge is in the WWW-Authenticate header",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "RFC 9457 problem details describing the payment requirement."
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/ErrorResponse"
          }
        }
      }
    }
  }
}
