{
  "components": {
    "parameters": {},
    "responses": {
      "Error": {
        "content": {
          "application/json": {
            "schema": {
              "properties": {
                "error": {
                  "type": "string"
                }
              },
              "type": "object"
            }
          }
        },
        "description": "Error"
      }
    },
    "schemas": {
      "InvoiceInput": {
        "properties": {
          "allowPartial": {
            "description": "Let the payer pay part of the balance now",
            "type": "boolean"
          },
          "billTo": {
            "$ref": "#/components/schemas/Party",
            "description": "The customer. name is required; email is prefilled at checkout."
          },
          "currency": {
            "default": "usd",
            "enum": [
              "usd",
              "cad",
              "eur",
              "gbp",
              "aud",
              "nzd"
            ],
            "type": "string"
          },
          "discount": {
            "description": "Minor units, taken off the subtotal",
            "minimum": 0,
            "type": "integer"
          },
          "dueDate": {
            "description": "YYYY-MM-DD. The invoice reads overdue the day after.",
            "format": "date",
            "type": "string"
          },
          "from": {
            "$ref": "#/components/schemas/Party",
            "description": "The business sending the invoice."
          },
          "issueDate": {
            "description": "YYYY-MM-DD",
            "format": "date",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/LineItem"
            },
            "maxItems": 100,
            "minItems": 1,
            "type": "array"
          },
          "minPayment": {
            "description": "Smallest partial payment in minor units (e.g. a deposit). The full balance is always payable.",
            "minimum": 0,
            "type": "integer"
          },
          "notes": {
            "maxLength": 2000,
            "type": "string"
          },
          "number": {
            "description": "Your invoice number, e.g. INV-1042",
            "maxLength": 40,
            "type": "string"
          },
          "shipTo": {
            "$ref": "#/components/schemas/Party",
            "description": "Optional shipping address"
          },
          "shipping": {
            "description": "Minor units, added after tax",
            "minimum": 0,
            "type": "integer"
          },
          "taxRate": {
            "description": "Percent. Applied after discount, not to shipping.",
            "maximum": 100,
            "minimum": 0,
            "type": "number"
          },
          "terms": {
            "maxLength": 2000,
            "type": "string"
          }
        },
        "required": [
          "billTo",
          "items"
        ],
        "type": "object"
      },
      "LineItem": {
        "properties": {
          "description": {
            "maxLength": 500,
            "type": "string"
          },
          "quantity": {
            "description": "May be fractional, e.g. 1.5 hours",
            "minimum": 0,
            "type": "number"
          },
          "unitPrice": {
            "description": "Minor units (cents)",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "description",
          "quantity",
          "unitPrice"
        ],
        "type": "object"
      },
      "PDFInput": {
        "description": "Direct PDF input. Western European (Windows-1252) text only, no logos, no payment ledger. Unknown text is rejected, never silently replaced.",
        "properties": {
          "billTo": {
            "$ref": "#/components/schemas/Party",
            "description": "The customer. name is required; email is prefilled at checkout."
          },
          "currency": {
            "default": "usd",
            "enum": [
              "usd",
              "cad",
              "eur",
              "gbp",
              "aud",
              "nzd"
            ],
            "type": "string"
          },
          "discount": {
            "description": "Minor units, taken off the subtotal",
            "minimum": 0,
            "type": "integer"
          },
          "dueDate": {
            "description": "YYYY-MM-DD. The invoice reads overdue the day after.",
            "format": "date",
            "type": "string"
          },
          "from": {
            "$ref": "#/components/schemas/Party",
            "description": "The business sending the invoice."
          },
          "issueDate": {
            "description": "YYYY-MM-DD",
            "format": "date",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/LineItem"
            },
            "maxItems": 100,
            "minItems": 1,
            "type": "array"
          },
          "notes": {
            "maxLength": 2000,
            "type": "string"
          },
          "number": {
            "description": "Your invoice number, e.g. INV-1042",
            "maxLength": 40,
            "type": "string"
          },
          "shipTo": {
            "$ref": "#/components/schemas/Party",
            "description": "Optional shipping address"
          },
          "shipping": {
            "description": "Minor units, added after tax",
            "minimum": 0,
            "type": "integer"
          },
          "taxRate": {
            "description": "Percent. Applied after discount, not to shipping.",
            "maximum": 100,
            "minimum": 0,
            "type": "number"
          },
          "terms": {
            "maxLength": 2000,
            "type": "string"
          }
        },
        "required": [
          "from",
          "billTo",
          "number",
          "issueDate",
          "dueDate",
          "items"
        ],
        "type": "object"
      },
      "Party": {
        "properties": {
          "address": {
            "description": "Multi-line postal address",
            "maxLength": 500,
            "type": "string"
          },
          "email": {
            "format": "email",
            "type": "string"
          },
          "name": {
            "maxLength": 200,
            "type": "string"
          }
        },
        "type": "object"
      },
      "TemplateInput": {
        "properties": {
          "billTo": {
            "$ref": "#/components/schemas/Party",
            "description": "The customer. name is required; email is prefilled at checkout."
          },
          "dueDate": {
            "description": "YYYY-MM-DD. The invoice reads overdue the day after.",
            "format": "date",
            "type": "string"
          },
          "from": {
            "$ref": "#/components/schemas/Party",
            "description": "The business sending the invoice."
          },
          "issueDate": {
            "description": "YYYY-MM-DD",
            "format": "date",
            "type": "string"
          },
          "number": {
            "description": "Your invoice number, e.g. INV-1042",
            "maxLength": 40,
            "type": "string"
          },
          "templateId": {
            "enum": [
              "consulting_hourly",
              "consulting_retainer",
              "consulting_milestone",
              "contractor_labor",
              "contractor_deposit"
            ],
            "type": "string"
          }
        },
        "required": [
          "templateId"
        ],
        "type": "object"
      },
      "Totals": {
        "properties": {
          "balance": {
            "type": "integer"
          },
          "daysLate": {
            "type": "integer"
          },
          "disputed": {
            "description": "Under an open dispute. Still counted as paid until the dispute is lost.",
            "type": "integer"
          },
          "paid": {
            "description": "Net of refunds and lost disputes",
            "type": "integer"
          },
          "refunded": {
            "description": "Refunds; always 0 on a draft",
            "type": "integer"
          },
          "status": {
            "enum": [
              "open",
              "partial",
              "overdue",
              "paid",
              "void"
            ],
            "type": "string"
          },
          "subtotal": {
            "type": "integer"
          },
          "tax": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          }
        },
        "type": "object"
      }
    }
  },
  "info": {
    "contact": {
      "name": "Alder",
      "url": "https://meetalder.com"
    },
    "description": "No account or key. `POST /api/v1/drafts` returns the totals and `builderUrl`, which opens the invoice filled in, ready to download as a PDF. All money is integer minor units (cents): 12.50 USD is 1250.\n\nMCP: the same as the `draft_invoice` tool over Streamable HTTP at `https://alderinvoices.com/mcp`.",
    "summary": "Free AI invoice generator: price an invoice and get a prefilled link to download it as a PDF.",
    "title": "AI Invoice Generator API (by Alder)",
    "version": "1.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/api/v1/drafts": {
      "post": {
        "description": "Nothing is stored. `builderUrl` opens the free builder with the invoice filled in, ready to review and download as a PDF.",
        "operationId": "draftInvoice",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "builderUrl": {
                      "format": "uri",
                      "type": "string"
                    },
                    "note": {
                      "type": "string"
                    },
                    "totals": {
                      "$ref": "#/components/schemas/Totals"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Draft"
          },
          "400": {
            "$ref": "#/components/responses/Error"
          }
        },
        "security": [],
        "summary": "Price an invoice and get a prefilled builder link (no account needed)"
      }
    },
    "/api/v1/pdf": {
      "post": {
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PDFInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/pdf": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "description": "Invalid input"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "security": [],
        "summary": "Render an invoice PDF"
      }
    },
    "/api/v1/template-drafts": {
      "post": {
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "description": "Invalid input"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "security": [],
        "summary": "Prepare a template draft"
      }
    },
    "/api/v1/templates": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "templates": {
                      "items": {
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "description": "Invalid input"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "security": [],
        "summary": "List invoice templates"
      }
    }
  },
  "servers": [
    {
      "url": "https://alderinvoices.com"
    }
  ]
}