{
  "openapi": "3.1.0",
  "info": {
    "title": "DealerSlip Invoice API",
    "version": "1.0.0",
    "description": "Prepare standalone UK vehicle sales invoice drafts from supplied facts. No model calls, account access, storage or sending. PDF download happens in the browser through the returned private review link. Users must confirm facts and tax treatment."
  },
  "servers": [
    {
      "url": "https://dealerslip.com"
    }
  ],
  "security": [],
  "paths": {
    "/api/v1/invoices": {
      "post": {
        "operationId": "createInvoice",
        "summary": "Prepare a vehicle sales invoice draft",
        "description": "Use only user-supplied facts. Ask for missing required values and explicit tax treatment. Do not invent mileage, payments or terms. Maximum request size 24 KB. Return the private review link to the user; do not publish it.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "ref": {
                    "type": "string",
                    "maxLength": 60,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])",
                    "minLength": 1
                  },
                  "date": {
                    "type": "string",
                    "pattern": "^(?:[0-9]{4}-[0-9]{2}-[0-9]{2})?$(?![\\s\\S])",
                    "description": "Full calendar date YYYY-MM-DD; blank when not supplied.",
                    "minLength": 1
                  },
                  "seller": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 160,
                        "pattern": "^[^\\r\\n]*$(?![\\s\\S])",
                        "minLength": 1
                      },
                      "address": {
                        "type": "string",
                        "maxLength": 700,
                        "pattern": "^[^\\r\\n]*(?:\\r?\\n[^\\r\\n]*){0,12}$(?![\\s\\S])",
                        "minLength": 1
                      },
                      "email": {
                        "type": "string",
                        "maxLength": 254,
                        "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                      },
                      "phone": {
                        "type": "string",
                        "maxLength": 60,
                        "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                      },
                      "vat": {
                        "type": "string",
                        "maxLength": 60,
                        "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                      },
                      "terms": {
                        "type": "string",
                        "maxLength": 3000,
                        "pattern": "^[^\\r\\n]*(?:\\r?\\n[^\\r\\n]*){0,12}$(?![\\s\\S])"
                      }
                    },
                    "required": [
                      "name",
                      "address"
                    ]
                  },
                  "customer": {
                    "type": "string",
                    "maxLength": 160,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])",
                    "minLength": 1
                  },
                  "address": {
                    "type": "string",
                    "maxLength": 700,
                    "pattern": "^[^\\r\\n]*(?:\\r?\\n[^\\r\\n]*){0,12}$(?![\\s\\S])",
                    "minLength": 1
                  },
                  "registration": {
                    "type": "string",
                    "maxLength": 16,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])",
                    "minLength": 1
                  },
                  "make": {
                    "type": "string",
                    "maxLength": 100,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])",
                    "minLength": 1
                  },
                  "model": {
                    "type": "string",
                    "maxLength": 100,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])",
                    "minLength": 1
                  },
                  "price": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 10000000,
                    "multipleOf": 0.01
                  },
                  "tax": {
                    "type": "string",
                    "enum": [
                      "margin",
                      "standard",
                      "none"
                    ],
                    "description": "Explicit user-selected VAT treatment. Standard prices include VAT at 20%; do not infer eligibility.",
                    "minLength": 1
                  },
                  "collection": {
                    "type": "string",
                    "pattern": "^(?:[0-9]{4}-[0-9]{2}-[0-9]{2})?$(?![\\s\\S])",
                    "description": "Full calendar date YYYY-MM-DD; blank when not supplied."
                  },
                  "firstRegistered": {
                    "type": "string",
                    "pattern": "^(?:[0-9]{4}-[0-9]{2}-[0-9]{2})?$(?![\\s\\S])",
                    "description": "Full calendar date YYYY-MM-DD; blank when not supplied."
                  },
                  "mot": {
                    "type": "string",
                    "pattern": "^(?:[0-9]{4}-[0-9]{2}-[0-9]{2})?$(?![\\s\\S])",
                    "description": "Full calendar date YYYY-MM-DD; blank when not supplied."
                  },
                  "derivative": {
                    "type": "string",
                    "maxLength": 160,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "year": {
                    "type": "string",
                    "maxLength": 4,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "mileage": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 10000000
                  },
                  "colour": {
                    "type": "string",
                    "maxLength": 80,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "vin": {
                    "type": "string",
                    "maxLength": 60,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "stock": {
                    "type": "string",
                    "maxLength": 60,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "phone": {
                    "type": "string",
                    "maxLength": 60,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "email": {
                    "type": "string",
                    "maxLength": 254,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 3000,
                    "pattern": "^[^\\r\\n]*(?:\\r?\\n[^\\r\\n]*){0,12}$(?![\\s\\S])"
                  },
                  "terms": {
                    "type": "string",
                    "maxLength": 3000,
                    "pattern": "^[^\\r\\n]*(?:\\r?\\n[^\\r\\n]*){0,12}$(?![\\s\\S])"
                  },
                  "pxOn": {
                    "type": "boolean"
                  },
                  "pxReg": {
                    "type": "string",
                    "maxLength": 16,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "pxModel": {
                    "type": "string",
                    "maxLength": 180,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "pxAllowance": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 10000000,
                    "multipleOf": 0.01
                  },
                  "pxSettlement": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 10000000,
                    "multipleOf": 0.01
                  },
                  "pxLender": {
                    "type": "string",
                    "maxLength": 160,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "pxMileage": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 10000000
                  },
                  "pxStock": {
                    "type": "string",
                    "maxLength": 60,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "pxVin": {
                    "type": "string",
                    "maxLength": 60,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "pxV5": {
                    "type": "string",
                    "maxLength": 300,
                    "pattern": "^[^\\r\\n]*(?:\\r?\\n[^\\r\\n]*){0,12}$(?![\\s\\S])"
                  },
                  "pxHistory": {
                    "type": "string",
                    "maxLength": 700,
                    "pattern": "^[^\\r\\n]*(?:\\r?\\n[^\\r\\n]*){0,12}$(?![\\s\\S])"
                  },
                  "pxDeclaration": {
                    "type": "string",
                    "maxLength": 3000,
                    "pattern": "^[^\\r\\n]*(?:\\r?\\n[^\\r\\n]*){0,12}$(?![\\s\\S])"
                  },
                  "finance": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 10000000,
                    "multipleOf": 0.01
                  },
                  "financeCompany": {
                    "type": "string",
                    "maxLength": 160,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "balanceMethod": {
                    "type": "string",
                    "maxLength": 160,
                    "pattern": "^[^\\r\\n]*$(?![\\s\\S])"
                  },
                  "extras": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "label": {
                          "type": "string",
                          "maxLength": 160,
                          "pattern": "^[^\\r\\n]*$(?![\\s\\S])",
                          "minLength": 1
                        },
                        "amount": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 10000000,
                          "multipleOf": 0.01
                        },
                        "tax": {
                          "type": "string",
                          "enum": [
                            "20",
                            "0"
                          ]
                        }
                      },
                      "required": [
                        "label",
                        "amount",
                        "tax"
                      ]
                    }
                  },
                  "payments": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "label": {
                          "type": "string",
                          "maxLength": 100,
                          "pattern": "^[^\\r\\n]*$(?![\\s\\S])",
                          "minLength": 1
                        },
                        "amount": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 10000000,
                          "multipleOf": 0.01
                        },
                        "method": {
                          "type": "string",
                          "maxLength": 100,
                          "pattern": "^[^\\r\\n]*$(?![\\s\\S])",
                          "minLength": 1
                        }
                      },
                      "required": [
                        "label",
                        "amount",
                        "method"
                      ]
                    }
                  }
                },
                "required": [
                  "ref",
                  "date",
                  "seller",
                  "customer",
                  "address",
                  "registration",
                  "make",
                  "model",
                  "price",
                  "tax"
                ],
                "allOf": [
                  {
                    "if": {
                      "properties": {
                        "pxOn": {
                          "const": true
                        }
                      },
                      "required": [
                        "pxOn"
                      ]
                    },
                    "then": {
                      "required": [
                        "pxAllowance"
                      ]
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Draft prepared; review and download required.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "invoice",
                    "totals",
                    "review_url",
                    "status",
                    "message"
                  ],
                  "properties": {
                    "invoice": {
                      "type": "object",
                      "description": "Normalized standalone draft. No account save or issuing action."
                    },
                    "totals": {
                      "type": "object",
                      "properties": {
                        "vehicle": {
                          "type": "number"
                        },
                        "extras": {
                          "type": "number"
                        },
                        "total": {
                          "type": "number"
                        },
                        "allowance": {
                          "type": "number"
                        },
                        "settlement": {
                          "type": "number"
                        },
                        "net": {
                          "type": "number"
                        },
                        "paid": {
                          "type": "number"
                        },
                        "finance": {
                          "type": "number"
                        },
                        "balance": {
                          "type": "number"
                        },
                        "vat": {
                          "type": "number"
                        }
                      }
                    },
                    "review_url": {
                      "type": "string",
                      "format": "uri",
                      "description": "Private link containing invoice details. Show only to the requesting user. Open to review and download browser-generated PDFs."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "draft"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, unsupported method or temporary service limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Invalid request, unsupported method or temporary service limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Invalid request, unsupported method or temporary service limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "Invalid request, unsupported method or temporary service limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Invalid request, unsupported method or temporary service limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Invalid request, unsupported method or temporary service limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/schema": {
      "get": {
        "operationId": "getInvoiceSchema",
        "summary": "Read the invoice input schema",
        "responses": {
          "200": {
            "description": "JSON Schema for invoice creation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  }
}
