{
  "openapi": "3.1.0",
  "info": {
    "title": "Postbot",
    "version": "1.0.0",
    "description": "Send real physical letters in the Czech Republic from an AI agent, CLI, or the web. Backed by Česká pošta (DopisOnline).",
    "contact": {
      "email": "ladi@amentistudio.com"
    }
  },
  "x-service-info": {
    "name": "Postbot",
    "description": "Physical letter delivery across the Czech Republic for AI agents.",
    "categories": [
      "postal",
      "printing",
      "logistics",
      "communication"
    ],
    "docs": {
      "homepage": "https://postbot.cz",
      "apiReference": "https://postbot.cz/openapi.json",
      "llms": "https://postbot.cz/llms.txt"
    }
  },
  "servers": [
    {
      "url": "https://postbot.cz"
    }
  ],
  "paths": {
    "/api/send": {
      "post": {
        "summary": "Send a physical letter",
        "description": "Prints, envelopes, and mails a letter via Česká pošta. Charged against the account's prepaid CZK credit; the price is computed from the rendered PDF (postage band + print). An unfunded account gets 402 with a top-up URL.",
        "operationId": "sendLetter",
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-payment-info": {
          "intent": "session",
          "method": "stripe",
          "amount": null,
          "currency": "CZK",
          "description": "Charged from prepaid CZK credit; priced per letter from the rendered PDF."
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Same input as the MCP `send_letter_cz` tool."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Letter accepted by Česká pošta."
          },
          "401": {
            "description": "Missing/invalid API key and the body was not a valid letter."
          },
          "402": {
            "description": "Payment required. Body carries both funding rails for this exact letter: rails.oneoff.payUrl (ready Stripe pay-link, no account — the letter mails once paid) and rails.credit.topupUrl (prepaid balance). Returned both for unauthenticated calls with a valid letter (error=payment_required) and for funded accounts with a low balance (error=insufficient_credit, plus balance/needed/topupUrl)."
          }
        }
      }
    },
    "/api/topup": {
      "post": {
        "summary": "Top up prepaid CZK credit",
        "description": "Funds the account's prepaid balance via Stripe. Returns a Stripe Checkout URL.",
        "operationId": "topUp",
        "x-payment-info": {
          "intent": "session",
          "method": "stripe",
          "amount": "500",
          "currency": "CZK",
          "description": "Establishes/extends prepaid balance. Minimum 500 Kč."
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amountCzk": {
                    "type": "integer",
                    "minimum": 500
                  }
                },
                "required": [
                  "amountCzk"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Stripe Checkout URL to fund credit."
          }
        }
      }
    },
    "/api/preview": {
      "post": {
        "summary": "Preview + firm-price a letter (no order, no payment)",
        "description": "Renders the letter to the exact PDF that would be printed and returns it with the firm price. No side effects — use before /api/send or /api/oneoff to show a human what will mail.",
        "operationId": "previewLetter",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Same input as the MCP `send_letter_cz` tool."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rendered preview: {pdfBase64, sheets, service, chargeCzk, payCzk}."
          },
          "400": {
            "description": "Invalid letter input."
          }
        }
      }
    },
    "/api/oneoff": {
      "post": {
        "summary": "Pay for a single letter (no account)",
        "description": "One-off card payment for one letter. Prices the rendered PDF, returns a pay URL.",
        "operationId": "oneOff",
        "x-payment-info": {
          "intent": "charge",
          "method": "stripe",
          "amount": null,
          "currency": "CZK",
          "description": "Single-letter card payment, priced from the PDF. Minimum 50 Kč."
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Letter input to price and mail."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pay URL for the quoted letter."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "pb_...",
        "description": "Postbot API key: `Authorization: Bearer pb_...`."
      }
    }
  }
}