{
  "openapi": "3.0.3",
  "info": {
    "title": "FiKS — ERP Gateway",
    "version": "0.6.0",
    "description": "FiKS hosted API: merchant registration, tenant-scoped receipt intake, immutable receipt events and printed JSON archive, monthly reports, and signed webhook outbox. SIMULATION ONLY: live ATK/printer acknowledgements are rejected. ERP and connector keys are separate."
  },
  "servers": [
    {
      "url": "https://fiks.ictility.com"
    }
  ],
  "security": [
    {
      "ERPKey": []
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "summary": "Liveness and simulation mode",
        "security": [],
        "responses": {
          "200": {
            "description": "Healthy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/profile": {
      "get": {
        "summary": "Authenticated ERP profile, without credentials",
        "responses": {
          "200": {
            "description": "Profile",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "X-Company-ID",
          "in": "header",
          "required": false,
          "description": "Required for admin access to company transactions; optional for profile. A company key cannot select another company.",
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/api/v1/transactions": {
      "post": {
        "summary": "Accept one ERP sale",
        "description": "202 means durably queued, not printed or fiscalized. Same source + key OR source + external_id + identical normalized content returns the existing transaction. Changed content returns 409. Keys are source-scoped. Merchant identity comes from server configuration. Body limit 1 MiB.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaleInput"
              },
              "example": {
                "external_id": "ERP-DEMO-00001",
                "branch_id": "PR-01",
                "pos_id": "POS-01",
                "operator_id": "OP-DEMO",
                "type": "SALE",
                "currency": "EUR",
                "items": [
                  {
                    "code": "SVC-DEMO",
                    "name": "Shërbim provues",
                    "unit": "cope",
                    "quantity": "1",
                    "unit_price": "11.8000",
                    "tax_category": "STANDARD"
                  }
                ],
                "payments": [
                  {
                    "method": "BANK_TRANSFER",
                    "amount": "11.80"
                  }
                ],
                "total": "11.80",
                "tax_total": "1.80"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued for simulation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction": {
                      "$ref": "#/components/schemas/Transaction"
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "200": {
            "description": "Existing identical transaction",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction": {
                      "$ref": "#/components/schemas/Transaction"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "Latest 100 transactions, newest first; counts cover the whole source",
        "responses": {
          "200": {
            "description": "Source-scoped transactions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transactions": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Transaction"
                      }
                    },
                    "counts": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "integer"
                      }
                    },
                    "limit": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "X-Company-ID",
          "in": "header",
          "required": false,
          "description": "Required for admin access to company transactions; optional for profile. A company key cannot select another company.",
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/api/v1/transactions/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        },
        {
          "name": "X-Company-ID",
          "in": "header",
          "required": false,
          "description": "Required for admin access to company transactions; optional for profile. A company key cannot select another company.",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Poll the transaction status",
        "responses": {
          "200": {
            "description": "Transaction",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction": {
                      "$ref": "#/components/schemas/Transaction"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/transactions/{id}/audit": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        },
        {
          "name": "X-Company-ID",
          "in": "header",
          "required": false,
          "description": "Required for admin access to company transactions; optional for profile. A company key cannot select another company.",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Append-only event history",
        "responses": {
          "200": {
            "description": "Audit events",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/transactions/{id}/reconcile": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        },
        {
          "name": "X-Company-ID",
          "in": "header",
          "required": false,
          "description": "Required for admin access to company transactions; optional for profile. A company key cannot select another company.",
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "summary": "Resolve an unknown outcome using durable simulator evidence",
        "description": "Does not resend. Allowed only in OUTCOME_UNKNOWN. Returns 409 if no evidence exists; manual investigation remains necessary.",
        "responses": {
          "200": {
            "description": "Reconciled simulation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction": {
                      "$ref": "#/components/schemas/Transaction"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/transactions/{id}/atk-preview": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        },
        {
          "name": "X-Company-ID",
          "in": "header",
          "required": false,
          "description": "Required for admin access to company transactions; optional for profile. A company key cannot select another company.",
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "summary": "Prepare official-schema Protobuf and signed demo envelopes offline",
        "description": "Uses the pinned ATK-linked models.proto and the Go reference DER ECDSA signing flow. All ATK IDs and keys are demo only. No network transport exists. Returns can_submit=false and fiscalized=false. Discounts are blocked pending verified mapping. BANK_TRANSFER explicitly maps to Other for this preview only.",
        "responses": {
          "200": {
            "description": "Offline demo protocol preview",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "503": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/companies": {
      "get": {
        "summary": "Administrator: list registered companies without credentials",
        "responses": {
          "200": {
            "description": "Company metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "companies": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Administrator: create any company and its scoped API key",
        "description": "Company ID and merchant_id must be unique and cannot overwrite an existing company. The generated API key appears in this response only. This is a local simulation profile, not ATK registration.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "id": {
                    "type": "string",
                    "maxLength": 64,
                    "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 160
                  },
                  "merchant_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 40
                  },
                  "vat_number": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "address": {
                    "type": "string",
                    "maxLength": 240
                  },
                  "erp_name": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "platform": {
                    "type": "string",
                    "maxLength": 300,
                    "description": "Optional HTTP/HTTPS ERP URL, without credentials, query or fragment. Metadata only; no remote connection is made."
                  }
                },
                "required": [
                  "id",
                  "name",
                  "merchant_id"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Company created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "company": {
                      "type": "object"
                    },
                    "api_key": {
                      "type": "string",
                      "format": "password"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/products": {
      "get": {
        "summary": "List the company catalog (up to 500 products)",
        "responses": {
          "200": {
            "description": "Products",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a company-scoped product",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "code": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 160
                  },
                  "unit": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 30
                  },
                  "unit_price": {
                    "type": "string",
                    "pattern": "^\\d{1,10}(?:\\.\\d{1,4})?$",
                    "description": "Decimal string; not a floating point JSON number."
                  },
                  "tax_category": {
                    "type": "string",
                    "enum": [
                      "STANDARD",
                      "REDUCED",
                      "ZERO",
                      "EXEMPT"
                    ]
                  },
                  "category": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "barcode": {
                    "type": "string",
                    "maxLength": 80
                  }
                },
                "required": [
                  "code",
                  "name",
                  "unit",
                  "unit_price",
                  "tax_category"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Product",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "X-Company-ID",
          "in": "header",
          "required": false,
          "description": "Required for admin access to company transactions; optional for profile. A company key cannot select another company.",
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/api/v1/products/demo": {
      "post": {
        "summary": "Explicitly add demonstration products without overwriting existing codes",
        "responses": {
          "200": {
            "description": "Catalog",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "X-Company-ID",
          "in": "header",
          "required": false,
          "description": "Required for admin access to company transactions; optional for profile. A company key cannot select another company.",
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/api/v1/reports/summary": {
      "get": {
        "summary": "All-time totals of SIMULATED transactions only; never a tax X/Z report",
        "responses": {
          "200": {
            "description": "Simulation totals and payment breakdown",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "X-Company-ID",
          "in": "header",
          "required": false,
          "description": "Required for admin access to company transactions; optional for profile. A company key cannot select another company.",
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/api/v1/pos/sales": {
      "post": {
        "summary": "Create a simulated sale with server-derived catalog prices",
        "description": "Prices and VAT are derived on the server from company-owned product IDs. The same stable Idempotency-Key and external_id must be retained after an uncertain response. No actual payment is made.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "external_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 160
                  },
                  "branch_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 160
                  },
                  "pos_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 160
                  },
                  "operator_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 160
                  },
                  "items": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "properties": {
                        "product_id": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 64
                        },
                        "quantity": {
                          "type": "string",
                          "pattern": "^\\d{1,10}(?:\\.\\d{1,3})?$",
                          "description": "Decimal string; not a floating point JSON number."
                        }
                      },
                      "required": [
                        "product_id",
                        "quantity"
                      ]
                    }
                  },
                  "payment_method": {
                    "type": "string",
                    "enum": [
                      "CASH",
                      "CARD",
                      "BANK_TRANSFER",
                      "VOUCHER",
                      "OTHER"
                    ]
                  }
                },
                "required": [
                  "external_id",
                  "branch_id",
                  "pos_id",
                  "operator_id",
                  "items",
                  "payment_method"
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Durably queued simulation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction": {
                      "$ref": "#/components/schemas/Transaction"
                    }
                  }
                }
              }
            }
          },
          "200": {
            "description": "Existing sale",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction": {
                      "$ref": "#/components/schemas/Transaction"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "X-Company-ID",
          "in": "header",
          "required": false,
          "description": "Required for admin access to company transactions; optional for profile. A company key cannot select another company.",
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/api/v1/merchants": {
      "get": {
        "summary": "List registered merchants (administrator only)",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        }
      },
      "post": {
        "summary": "Register merchant; return its ERP key and dedicated receipt endpoint",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MerchantInput"
              }
            }
          }
        }
      }
    },
    "/api/v1/merchants/{merchant}/receipts": {
      "get": {
        "summary": "Latest 100 receipts of this merchant, with lifecycle status",
        "parameters": [
          {
            "in": "path",
            "name": "merchant",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        }
      },
      "post": {
        "summary": "Accept receipt and record fiks.received once; original JSON and amounts are immutable",
        "parameters": [
          {
            "in": "path",
            "name": "merchant",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 160
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaleInput"
              }
            }
          }
        }
      }
    },
    "/api/v1/merchants/{merchant}/receipts/{id}": {
      "get": {
        "summary": "Read receipt, lifecycle, document_sha256 and archive metadata",
        "parameters": [
          {
            "in": "path",
            "name": "merchant",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        }
      }
    },
    "/api/v1/merchants/{merchant}/receipts/{id}/events": {
      "get": {
        "summary": "Read immutable lifecycle event history",
        "parameters": [
          {
            "in": "path",
            "name": "merchant",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        }
      }
    },
    "/api/v1/merchants/{merchant}/receipts/{id}/printed": {
      "get": {
        "summary": "Download immutable printed JSON snapshot and evidence; simulation only",
        "parameters": [
          {
            "in": "path",
            "name": "merchant",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        }
      }
    },
    "/api/v1/merchants/{merchant}/reports/monthly/{month}/{basis}": {
      "get": {
        "summary": "Monthly receipt counts, gross/net/VAT, payment totals and current statuses; Europe/Belgrade civil month",
        "parameters": [
          {
            "in": "path",
            "name": "merchant",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "month",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^20[0-9]{2}-(0[1-9]|1[0-2])$"
            }
          },
          {
            "in": "path",
            "name": "basis",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "accepted",
                "printed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        }
      }
    },
    "/api/v1/merchants/{merchant}/integration-key": {
      "post": {
        "summary": "Create/rotate separate connector key (administrator only)",
        "parameters": [
          {
            "in": "path",
            "name": "merchant",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        }
      }
    },
    "/api/v1/merchants/{merchant}/webhook": {
      "get": {
        "summary": "Read webhook configuration and latest 30 delivery results; never returns secret",
        "parameters": [
          {
            "in": "path",
            "name": "merchant",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        }
      },
      "post": {
        "summary": "Configure/rotate or disable signed webhook (administrator only). Reconfiguration cancels queued deliveries.",
        "parameters": [
          {
            "in": "path",
            "name": "merchant",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookConfiguration"
              }
            }
          }
        }
      }
    },
    "/api/v1/merchants/{merchant}/webhooks/dispatch": {
      "post": {
        "summary": "Dispatch up to five due deliveries for this merchant (administrator only)",
        "parameters": [
          {
            "in": "path",
            "name": "merchant",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        }
      }
    },
    "/api/v1/agent/receipts/{id}/events": {
      "post": {
        "summary": "Simulation connector acknowledgement: RECEIVED → SENT → ATK_RECEIVED → PRINTED → CLOSED; ERP key forbidden",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 160
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceiptAcknowledgement"
              }
            }
          }
        },
        "security": [
          {
            "ConnectorKey": []
          }
        ]
      }
    },
    "/api/v1/agent/webhooks/dispatch": {
      "post": {
        "summary": "Connector periodically dispatches due webhook deliveries for its own merchant",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful read or idempotent replay"
          },
          "201": {
            "description": "Created; returned credentials are shown once"
          },
          "202": {
            "description": "Receipt accepted and durably stored"
          },
          "400": {
            "description": "Invalid request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Wrong merchant or administrator/connector permission required"
          },
          "404": {
            "description": "Resource not found or no print confirmation"
          },
          "409": {
            "description": "Duplicate conflict, invalid transition, or live adapter unavailable"
          },
          "422": {
            "description": "Validation or webhook hostname error"
          }
        },
        "security": [
          {
            "ConnectorKey": []
          }
        ]
      }
    },
    "/api/v1/merchants/{merchant}/workflow": {
      "post": {
        "summary": "Set company front-end workflow (administrator only; fiscal mode unchanged)",
        "parameters": [
          {
            "name": "merchant",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "workflow_mode"
                ],
                "properties": {
                  "workflow_mode": {
                    "type": "string",
                    "enum": [
                      "ERP",
                      "POS"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Company profile with persisted workflow_mode"
          },
          "403": {
            "description": "Administrator required"
          },
          "422": {
            "description": "Invalid mode"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ERPKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Company-scoped ERP key or administrator key. Administrators select a company explicitly with X-Company-ID. Never put credentials in URLs."
      },
      "ConnectorKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Separate merchant-scoped connector credential; cannot act as an ERP key. Administrator provisions it using integration-key. Rotation revokes the old key."
      }
    },
    "schemas": {
      "SaleInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "external_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "branch_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "pos_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "operator_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "type": {
            "type": "string",
            "enum": [
              "SALE"
            ]
          },
          "currency": {
            "type": "string",
            "enum": [
              "EUR"
            ]
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "code": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 160
                },
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 160
                },
                "unit": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 160
                },
                "quantity": {
                  "type": "string",
                  "pattern": "^\\d{1,10}(?:\\.\\d{1,3})?$",
                  "description": "Decimal string; not a floating point JSON number."
                },
                "unit_price": {
                  "type": "string",
                  "pattern": "^\\d{1,10}(?:\\.\\d{1,4})?$",
                  "description": "Decimal string; not a floating point JSON number."
                },
                "discount": {
                  "type": "string",
                  "pattern": "^\\d{1,10}(?:\\.\\d{1,2})?$",
                  "description": "Decimal string; not a floating point JSON number."
                },
                "tax_category": {
                  "type": "string",
                  "enum": [
                    "EXEMPT",
                    "ZERO",
                    "REDUCED",
                    "STANDARD"
                  ]
                }
              },
              "required": [
                "code",
                "name",
                "unit",
                "quantity",
                "unit_price",
                "tax_category"
              ]
            },
            "minItems": 1,
            "maxItems": 200
          },
          "payments": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "method": {
                  "type": "string",
                  "enum": [
                    "CASH",
                    "CARD",
                    "BANK_TRANSFER",
                    "VOUCHER",
                    "OTHER"
                  ]
                },
                "amount": {
                  "type": "string",
                  "pattern": "^\\d{1,10}(?:\\.\\d{1,2})?$",
                  "description": "Decimal string; not a floating point JSON number."
                }
              },
              "required": [
                "method",
                "amount"
              ]
            },
            "minItems": 1,
            "maxItems": 10
          },
          "total": {
            "type": "string",
            "pattern": "^\\d{1,10}(?:\\.\\d{1,2})?$",
            "description": "Decimal string; not a floating point JSON number."
          },
          "tax_total": {
            "type": "string",
            "pattern": "^\\d{1,10}(?:\\.\\d{1,2})?$",
            "description": "Decimal string; not a floating point JSON number."
          }
        },
        "required": [
          "external_id",
          "branch_id",
          "pos_id",
          "operator_id",
          "type",
          "currency",
          "items",
          "payments",
          "total",
          "tax_total"
        ],
        "description": "Simulation-only sale. Prices include VAT. Discount is a gross amount per line. Draft policy: round quantity × unit price to cents HALF_UP, subtract discount, compute and round VAT per line HALF_UP. Not an ATK-certified arithmetic policy. External ID must be unique across the authenticated source, including branches."
      },
      "Transaction": {
        "type": "object",
        "required": [
          "id",
          "source",
          "merchant_id",
          "external_id",
          "status",
          "payload",
          "fiscalized",
          "mode"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "source": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "merchant_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "external_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 160
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "PROCESSING",
              "SIMULATED",
              "OUTCOME_UNKNOWN"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "payload": {
            "type": "object",
            "description": "Normalized input plus computed line totals, VAT, net_total and tax_groups."
          },
          "result": {
            "type": "object",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "mode": {
            "type": "string",
            "enum": [
              "SIMULATION"
            ]
          },
          "fiscalized": {
            "type": "boolean",
            "enum": [
              false
            ]
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "minLength": 1,
                "maxLength": 160
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "MerchantInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "merchant_id"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "merchant_id": {
            "type": "string"
          },
          "vat_number": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "country": {
            "type": "string",
            "default": "XK",
            "pattern": "^[A-Z]{2}$"
          },
          "contact_email": {
            "type": "string"
          },
          "contact_phone": {
            "type": "string"
          },
          "erp_name": {
            "type": "string"
          },
          "platform": {
            "type": "string"
          },
          "workflow_mode": {
            "type": "string",
            "enum": [
              "ERP",
              "POS"
            ],
            "default": "ERP",
            "description": "Company workspace preference, independent of SIMULATION. Does not revoke API access."
          }
        }
      },
      "ReceiptAcknowledgement": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status",
          "mode",
          "evidence"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "SENT",
              "ATK_RECEIVED",
              "PRINTED",
              "CLOSED"
            ]
          },
          "mode": {
            "type": "string",
            "enum": [
              "SIMULATION"
            ]
          },
          "evidence": {
            "type": "object",
            "description": "SENT: message_id; ATK_RECEIVED: response_reference + response_sha256; PRINTED: printer_id + printer_job_id + document_sha256 returned with the receipt; CLOSED: empty object. Hashes are lowercase 64-character SHA256."
          }
        }
      },
      "WebhookConfiguration": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "enabled"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS, no credentials/query/fragment; hostname must be in server-side WEBHOOK_ALLOWED_HOSTS."
          },
          "enabled": {
            "type": "boolean"
          }
        }
      }
    }
  }
}
