# Stable Pro API, v1 — generated from app/lib/api-esterna/contratto.ts: do not edit by hand.
# Rewrite with: npx tsx scripts/api/scriviIlContratto.ts
openapi: "3.1.0"
info:
  title: "Stable Pro API"
  version: "1.0.0"
  description: "Read the economic facts of a stable (charges, adjustments, payments, credits, receipts) and send back the documents your invoicing software issues. One contract for every software and every country. Amounts are integers in the minor units of their currency (ISO 4217); calendar dates are YYYY-MM-DD; instants are RFC 3339 in UTC; codes are open lists: accept values you do not know yet. Inside v1 there are only additions."
servers:
  - url: "https://app.stable-pro.com/api/v1"
    description: "Production: sp_live_ keys"
  - url: "https://staging.stable-pro.com/api/v1"
    description: "Staging, with test data: sp_test_ keys"
security:
  - bearer: []
paths:
  "/connection":
    get:
      summary: "The connection of the calling key: name, permissions, and the key itself (never the secret)"
      operationId: "getConnection"
      x-permission: null
      parameters:
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Connection"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/codes":
    get:
      summary: "The dictionary of every code the API returns, with names in the requested language (?lang=, Accept-Language)"
      operationId: "getCodes"
      x-permission: null
      parameters:
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Codes"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/organization":
    get:
      summary: "The stable of the calling key: name, country, currency, time zone, language, whether Stable Pro calculates taxes"
      operationId: "getOrganization"
      x-permission: null
      parameters:
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Organization"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/customers":
    get:
      summary: "Everyone with at least one charge, paid or not, member or staff; with customers.fiscal:read also the invoice details"
      operationId: "getCustomers"
      x-permission: "customers:read"
      parameters:
        - "$ref": "#/components/parameters/lang"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/starting_after"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/CustomerList"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/customers/{id}":
    get:
      summary: "One customer; with customers.fiscal:read also the invoice details. Not of this stable: 404"
      operationId: "getCustomersId"
      x-permission: "customers:read"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
            format: "uuid"
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Customer"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/customers/{id}/balance":
    get:
      summary: "What the customer owes today, what comes later, and the credit they can spend"
      operationId: "getCustomersIdBalance"
      x-permission: "charges:read"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
            format: "uuid"
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Balance"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/charges":
    get:
      summary: "Every charge to the customers, paid or not (never the staff pay)"
      operationId: "getCharges"
      x-permission: "charges:read"
      parameters:
        - "$ref": "#/components/parameters/lang"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/starting_after"
        - name: "customer"
          in: "query"
          required: false
          description: "Only this customer (its id)"
          schema:
            type: "string"
            format: "uuid"
        - name: "accounting_month"
          in: "query"
          required: false
          description: "Only this accounting month (YYYY-MM): the month the fact counts in, see Conventions"
          schema:
            type: "string"
            pattern: "^\\d{4}-(0[1-9]|1[0-2])$"
            examples:
              - "2026-10"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ChargeList"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/charges/{id}":
    get:
      summary: "One charge, as it is now: amount and taxes are birth plus adjustments plus tax changes"
      operationId: "getChargesId"
      x-permission: "charges:read"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
            format: "uuid"
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Charge"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/adjustments":
    get:
      summary: "Adjustments of charges"
      operationId: "getAdjustments"
      x-permission: "charges:read"
      parameters:
        - "$ref": "#/components/parameters/lang"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/starting_after"
        - name: "charge"
          in: "query"
          required: false
          description: "Only the adjustments of this charge (its id)"
          schema:
            type: "string"
            format: "uuid"
        - name: "accounting_month"
          in: "query"
          required: false
          description: "Only this accounting month (YYYY-MM): the month the fact counts in, see Conventions"
          schema:
            type: "string"
            pattern: "^\\d{4}-(0[1-9]|1[0-2])$"
            examples:
              - "2026-10"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AdjustmentList"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/adjustments/{id}":
    get:
      summary: "One adjustment: action, reason, category, signed amount, consideration_effect, the tax difference"
      operationId: "getAdjustmentsId"
      x-permission: "charges:read"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
            format: "uuid"
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Adjustment"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/payments":
    get:
      summary: "Money movements of the customers (payments, refunds, reversals, credit used)"
      operationId: "getPayments"
      x-permission: "payments:read"
      parameters:
        - "$ref": "#/components/parameters/lang"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/starting_after"
        - name: "customer"
          in: "query"
          required: false
          description: "Only this customer (its id)"
          schema:
            type: "string"
            format: "uuid"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/PaymentList"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/payments/{id}":
    get:
      summary: "One money movement, with its allocations; who paid on behalf of the customer"
      operationId: "getPaymentsId"
      x-permission: "payments:read"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
            format: "uuid"
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Payment"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/allocations/{id}":
    get:
      summary: "How much of a movement goes to a charge, signed"
      operationId: "getAllocationsId"
      x-permission: "payments:read"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
            format: "uuid"
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Allocation"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/credit-entries":
    get:
      summary: "Movements of the customers' credit (born, grown, used, refunded)"
      operationId: "getCredit-entries"
      x-permission: "payments:read"
      parameters:
        - "$ref": "#/components/parameters/lang"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/starting_after"
        - name: "customer"
          in: "query"
          required: false
          description: "Only this customer (its id)"
          schema:
            type: "string"
            format: "uuid"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/CreditEntryList"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/credit-entries/{id}":
    get:
      summary: "One movement of a customer's credit"
      operationId: "getCredit-entriesId"
      x-permission: "payments:read"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
            format: "uuid"
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/CreditEntry"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/receipts":
    get:
      summary: "Receipts of Stable Pro (R: payment receipts, RB: refund confirmations), in order of issue; never fiscal documents"
      operationId: "getReceipts"
      x-permission: "receipts:read"
      parameters:
        - "$ref": "#/components/parameters/lang"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/starting_after"
        - name: "customer"
          in: "query"
          required: false
          description: "Only this customer (its id)"
          schema:
            type: "string"
            format: "uuid"
        - name: "payment"
          in: "query"
          required: false
          description: "Only the receipts of this money movement (its id)"
          schema:
            type: "string"
            format: "uuid"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ReceiptList"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/receipts/{id}":
    get:
      summary: "One receipt: kind, the number as printed, status, the payment it confirms, the frozen amount"
      operationId: "getReceiptsId"
      x-permission: "receipts:read"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
            format: "uuid"
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Receipt"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/receipts/{id}/pdf":
    get:
      summary: "The PDF of the receipt, the same the customer got. When it carries the tax data of who paid on behalf of the customer, it also needs customers.fiscal:read (else 403)"
      operationId: "getReceiptsIdPdf"
      x-permission: "receipts:read"
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
            format: "uuid"
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "The document"
          content:
            "application/pdf":
              schema:
                type: "string"
                contentMediaType: "application/pdf"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/events":
    get:
      summary: "What happened, in order: read after your cursor to stay in sync. Each event needs the permission of the object it points to. While the stable's history is being loaded: 503 events-not-ready"
      operationId: "getEvents"
      x-permission: null
      parameters:
        - "$ref": "#/components/parameters/lang"
        - "$ref": "#/components/parameters/limit"
        - "$ref": "#/components/parameters/after"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/EventList"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
  "/events/{id}":
    get:
      summary: "One event. Of another stable, or of a kind your key does not read: 404"
      operationId: "getEventsId"
      x-permission: null
      parameters:
        - name: "id"
          in: "path"
          required: true
          schema:
            type: "string"
            format: "uuid"
        - "$ref": "#/components/parameters/lang"
      responses:
        "200":
          description: "OK"
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/Event"
        "400":
          description: "A parameter is not valid, or the route does not know it (invalid-request; invalid_param says which)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "401":
          description: "The key is missing or not valid (unauthorized; reason says why)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "403":
          description: "A permission is missing (forbidden), or the plan has no Accounting area (accounting-disabled)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "404":
          description: "Not found, or not of this stable: the two answers are identical (not-found)"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "429":
          description: "Too many requests (rate-limited): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "500":
          description: "Internal error"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
        "503":
          description: "Temporarily unavailable (unavailable), or the stable's events are being prepared (events-not-ready): wait Retry-After seconds"
          content:
            "application/problem+json":
              schema:
                "$ref": "#/components/schemas/Problem"
components:
  securitySchemes:
    bearer:
      type: "http"
      scheme: "bearer"
      description: "The key the stable owner creates in Settings → Connections. The stable comes from the key."
  parameters:
    lang:
      name: "lang"
      in: "query"
      required: false
      schema:
        type: "string"
        enum:
          - "en"
          - "it"
          - "fr"
          - "de"
          - "es"
      description: "Language of the sentences for people (wins over Accept-Language). Codes never change."
    limit:
      name: "limit"
      in: "query"
      required: false
      schema:
        type: "integer"
        minimum: 1
        maximum: 100
        default: 25
    starting_after:
      name: "starting_after"
      in: "query"
      required: false
      schema:
        type: "string"
        format: "uuid"
      description: "The id of the last item of the previous page"
    after:
      name: "after"
      in: "query"
      required: false
      schema:
        type: "string"
        format: "uuid"
      description: "The next_cursor of the previous answer. Without it, from the first event of the stable"
  schemas:
    Problem:
      type: "object"
      properties:
        type:
          type: "string"
          format: "uri"
          description: "Stable, in English: decide on this, not on the text"
        title:
          type: "string"
          description: "In English"
        status:
          type: "integer"
          minimum: 400
          maximum: 599
        detail:
          description: "A sentence for people, in the requested language (?lang=, Accept-Language)"
          type: "string"
        reason:
          description: "401 only: why the key is not valid"
          type: "string"
          enum:
            - "missing"
            - "malformed"
            - "wrong_environment"
            - "unknown"
            - "connection_revoked"
            - "revoked"
            - "expired"
            - "rotated"
        missing_permission:
          description: "403 forbidden only"
          type: "string"
          enum:
            - "charges:read"
            - "payments:read"
            - "receipts:read"
            - "customers:read"
            - "customers.fiscal:read"
            - "external-documents:write"
        invalid_param:
          description: "400 only: the parameter that is not valid"
          type: "string"
      required:
        - "type"
        - "title"
        - "status"
      additionalProperties: {}
    Connection:
      type: "object"
      properties:
        object:
          type: "string"
          const: "connection"
        id:
          type: "string"
          format: "uuid"
        name:
          type: "string"
        permissions:
          type: "array"
          items:
            type: "string"
            enum:
              - "charges:read"
              - "payments:read"
              - "receipts:read"
              - "customers:read"
              - "customers.fiscal:read"
              - "external-documents:write"
        created_at:
          type: "string"
          format: "date-time"
          description: "RFC 3339, UTC"
        key:
          type: "object"
          properties:
            id:
              type: "string"
              format: "uuid"
            last_four:
              type: "string"
              minLength: 4
              maxLength: 4
            environment:
              type: "string"
              enum:
                - "live"
                - "test"
              description: "live = production (sp_live_), test = staging (sp_test_)"
            created_at:
              type: "string"
              format: "date-time"
              description: "RFC 3339, UTC"
            expires_at:
              anyOf:
                - type: "string"
                  format: "date-time"
                  description: "RFC 3339, UTC"
                - type: "null"
            retires_at:
              anyOf:
                - type: "string"
                  format: "date-time"
                  description: "RFC 3339, UTC"
                - type: "null"
              description: "After a rotation: when this key stops working"
          required:
            - "id"
            - "last_four"
            - "environment"
            - "created_at"
            - "expires_at"
            - "retires_at"
          additionalProperties: false
      required:
        - "object"
        - "id"
        - "name"
        - "permissions"
        - "created_at"
        - "key"
      additionalProperties: false
    Organization:
      type: "object"
      properties:
        object:
          type: "string"
          const: "organization"
        id:
          type: "string"
          format: "uuid"
        name:
          type: "string"
        legal_name:
          anyOf:
            - type: "string"
            - type: "null"
        country:
          anyOf:
            - type: "string"
              minLength: 2
              maxLength: 2
            - type: "null"
          description: "ISO 3166-1 alpha-2"
        currency:
          type: "string"
          minLength: 3
          maxLength: 3
          description: "ISO 4217"
        timezone:
          type: "string"
          description: "IANA"
        language:
          type: "string"
          description: "The stable's language: Stable Pro does not know each customer's"
        locale:
          type: "string"
          description: "BCP 47, for formatting"
        taxes:
          type: "object"
          properties:
            calculated_by:
              type: "string"
              enum:
                - "stable_pro"
                - "external"
              description: "external = Stable Pro does not calculate taxes this month: nothing more"
            amount_basis:
              type: "string"
              const: "gross"
              description: "Every amount is the total the customer pays"
          required:
            - "calculated_by"
            - "amount_basis"
          additionalProperties: false
        receipts_shown_to_customers:
          type: "boolean"
          description: "false: the stable chose not to give Stable Pro receipts to its customers while software is connected; they still exist and are numbered (GET /receipts)"
      required:
        - "object"
        - "id"
        - "name"
        - "legal_name"
        - "country"
        - "currency"
        - "timezone"
        - "language"
        - "locale"
        - "taxes"
        - "receipts_shown_to_customers"
      additionalProperties: false
    Customer:
      type: "object"
      properties:
        object:
          type: "string"
          const: "customer"
        id:
          type: "string"
          format: "uuid"
          description: "The customer code: it never changes"
        kind:
          type: "string"
          enum:
            - "member"
            - "staff"
        name:
          type: "string"
        given_name:
          anyOf:
            - type: "string"
            - type: "null"
        family_name:
          anyOf:
            - type: "string"
            - type: "null"
        active:
          type: "boolean"
          description: "false: left the stable, or removed; their charges are still invoiceable"
        created_at:
          type: "string"
          format: "date-time"
          description: "RFC 3339, UTC"
        billing_address:
          description: "customers.fiscal:read only"
          anyOf:
            - type: "object"
              properties:
                line1:
                  anyOf:
                    - type: "string"
                    - type: "null"
                line2:
                  anyOf:
                    - type: "string"
                    - type: "null"
                postal_code:
                  anyOf:
                    - type: "string"
                    - type: "null"
                city:
                  anyOf:
                    - type: "string"
                    - type: "null"
                subdivision:
                  anyOf:
                    - type: "string"
                    - type: "null"
                  description: "ISO 3166-2 (IT-MI, US-OH)"
                country:
                  anyOf:
                    - type: "string"
                    - type: "null"
                  description: "ISO 3166-1 alpha-2"
              required:
                - "line1"
                - "line2"
                - "postal_code"
                - "city"
                - "subdivision"
                - "country"
              additionalProperties: false
            - type: "null"
        billing_address_text:
          description: "customers.fiscal:read only: the old free-text address, only while billing_address is empty"
          anyOf:
            - type: "string"
            - type: "null"
        tax_identifiers:
          description: "customers.fiscal:read only"
          type: "array"
          items:
            type: "object"
            properties:
              scheme:
                type: "string"
                description: "VAT, or an ISO 6523 ICD (0210 Italian fiscal code, 0211 Italian VAT number)"
              value:
                type: "string"
            required:
              - "scheme"
              - "value"
            additionalProperties: false
        tax_code:
          description: "customers.fiscal:read only: the old fiscal code, without a scheme"
          anyOf:
            - type: "string"
            - type: "null"
      required:
        - "object"
        - "id"
        - "kind"
        - "name"
        - "given_name"
        - "family_name"
        - "active"
        - "created_at"
      additionalProperties: false
    CustomerList:
      type: "object"
      properties:
        object:
          type: "string"
          const: "list"
        data:
          type: "array"
          items:
            "$ref": "#/components/schemas/Customer"
        has_more:
          type: "boolean"
          description: "There is a next page: ask again with starting_after = the id of the last item"
      required:
        - "object"
        - "data"
        - "has_more"
      additionalProperties: false
    Balance:
      type: "object"
      properties:
        object:
          type: "string"
          const: "balance"
        customer_id:
          type: "string"
          format: "uuid"
        currency:
          type: "string"
          minLength: 3
          maxLength: 3
        amount_due:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "What is due today: charges already visible"
        amount_scheduled:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Charges that become visible later"
        credit:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Credit that can be spent on a charge"
        as_of:
          type: "string"
          format: "date"
          description: "Today, in the stable's time zone"
      required:
        - "object"
        - "customer_id"
        - "currency"
        - "amount_due"
        - "amount_scheduled"
        - "credit"
        - "as_of"
      additionalProperties: false
    Charge:
      type: "object"
      properties:
        object:
          type: "string"
          const: "charge"
        id:
          type: "string"
          format: "uuid"
        customer_id:
          type: "string"
          format: "uuid"
        type:
          type: "string"
          description: "Open list: boarding, service_charge, lesson_drop_in, lesson_plan, health_record, …"
        description:
          type: "string"
          description: "As the stable wrote it"
        period_start:
          type: "string"
          format: "date"
          description: "YYYY-MM-DD"
        period_end:
          type: "string"
          format: "date"
          description: "YYYY-MM-DD"
        competence_month:
          type: "string"
          pattern: "^\\d{4}-\\d{2}$"
          description: "YYYY-MM"
        accounting_month:
          type: "string"
          pattern: "^\\d{4}-\\d{2}$"
          description: "The later of competence and registration month: computed by Stable Pro"
        due_date:
          type: "string"
          format: "date"
          description: "YYYY-MM-DD"
        visible_from:
          type: "string"
          format: "date"
          description: "YYYY-MM-DD"
        quantity:
          type: "number"
          const: 1
        unit:
          type: "string"
          enum:
            - "MON"
            - "ANN"
            - "C62"
          description: "UNECE Rec. 20"
        unit_amount:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Minor units of the currency (ISO 4217)"
        currency:
          type: "string"
          minLength: 3
          maxLength: 3
        original_amount:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "At birth"
        amount:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Now: birth plus adjustments"
        amount_paid:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Minor units of the currency (ISO 4217)"
        amount_remaining:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Minor units of the currency (ISO 4217)"
        amount_basis:
          type: "string"
          const: "gross"
        tax_calculated_by:
          type: "string"
          enum:
            - "stable_pro"
            - "external"
        tax_treatment:
          type: "string"
          enum:
            - "standard_rated"
            - "zero_rated"
            - "not_calculated"
            - "undetermined"
        taxable_amount:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Minor units of the currency (ISO 4217)"
        taxes:
          type: "array"
          items:
            type: "object"
            properties:
              type:
                type: "string"
                const: "vat"
                description: "Open list: other types may come"
              jurisdiction:
                anyOf:
                  - type: "string"
                  - type: "null"
                description: "ISO 3166-1 alpha-2 of the stable"
              category:
                anyOf:
                  - type: "string"
                  - type: "null"
                description: "UNCL 5305: S, Z, E, AE, K, G, O; null when not declared"
              rate_bp:
                type: "integer"
                minimum: -9007199254740991
                maximum: 9007199254740991
                description: "Basis points: 2200 = 22%"
              amount:
                type: "integer"
                minimum: -9007199254740991
                maximum: 9007199254740991
                description: "Minor units of the currency"
              exemption_reason:
                description: "BT-120, zero-rated only"
                anyOf:
                  - type: "string"
                  - type: "null"
              exemption_reason_code:
                description: "VATEX (BT-121), zero-rated only"
                anyOf:
                  - type: "string"
                  - type: "null"
            required:
              - "type"
              - "jurisdiction"
              - "category"
              - "rate_bp"
              - "amount"
            additionalProperties: false
        created_at:
          type: "string"
          format: "date-time"
          description: "RFC 3339, UTC"
      required:
        - "object"
        - "id"
        - "customer_id"
        - "type"
        - "description"
        - "period_start"
        - "period_end"
        - "competence_month"
        - "accounting_month"
        - "due_date"
        - "visible_from"
        - "quantity"
        - "unit"
        - "unit_amount"
        - "currency"
        - "original_amount"
        - "amount"
        - "amount_paid"
        - "amount_remaining"
        - "amount_basis"
        - "tax_calculated_by"
        - "tax_treatment"
        - "taxable_amount"
        - "taxes"
        - "created_at"
      additionalProperties: false
    ChargeList:
      type: "object"
      properties:
        object:
          type: "string"
          const: "list"
        data:
          type: "array"
          items:
            "$ref": "#/components/schemas/Charge"
        has_more:
          type: "boolean"
          description: "There is a next page: ask again with starting_after = the id of the last item"
      required:
        - "object"
        - "data"
        - "has_more"
      additionalProperties: false
    Adjustment:
      type: "object"
      properties:
        object:
          type: "string"
          const: "adjustment"
        id:
          type: "string"
          format: "uuid"
        charge_id:
          type: "string"
          format: "uuid"
        customer_id:
          type: "string"
          format: "uuid"
        direction:
          type: "string"
          const: "receivable"
        action:
          anyOf:
            - type: "string"
            - type: "null"
          description: "Open list of codes (see /codes)"
        reason:
          anyOf:
            - type: "string"
            - type: "null"
        category:
          anyOf:
            - type: "string"
            - type: "null"
        origin:
          anyOf:
            - type: "string"
            - type: "null"
          description: "HUMAN, SYSTEM, …"
        amount:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Signed: negative lowers the charge"
        consideration_effect:
          type: "string"
          enum:
            - "changes"
            - "none"
          description: "changes: a credit note (or debit note) follows; none: a credit loss, no tax"
        taxes:
          type: "array"
          items:
            type: "object"
            properties:
              type:
                type: "string"
                const: "vat"
                description: "Open list: other types may come"
              jurisdiction:
                anyOf:
                  - type: "string"
                  - type: "null"
                description: "ISO 3166-1 alpha-2 of the stable"
              category:
                anyOf:
                  - type: "string"
                  - type: "null"
                description: "UNCL 5305: S, Z, E, AE, K, G, O; null when not declared"
              rate_bp:
                type: "integer"
                minimum: -9007199254740991
                maximum: 9007199254740991
                description: "Basis points: 2200 = 22%"
              amount:
                type: "integer"
                minimum: -9007199254740991
                maximum: 9007199254740991
                description: "Minor units of the currency"
              exemption_reason:
                description: "BT-120, zero-rated only"
                anyOf:
                  - type: "string"
                  - type: "null"
              exemption_reason_code:
                description: "VATEX (BT-121), zero-rated only"
                anyOf:
                  - type: "string"
                  - type: "null"
            required:
              - "type"
              - "jurisdiction"
              - "category"
              - "rate_bp"
              - "amount"
            additionalProperties: false
          description: "With changes: the tax difference, already computed. With none: empty"
        taxable_amount:
          anyOf:
            - type: "integer"
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: "Minor units of the currency (ISO 4217)"
            - type: "null"
        currency:
          type: "string"
          minLength: 3
          maxLength: 3
        competence_month:
          type: "string"
          pattern: "^\\d{4}-\\d{2}$"
          description: "YYYY-MM"
        accounting_month:
          type: "string"
          pattern: "^\\d{4}-\\d{2}$"
          description: "YYYY-MM"
        occurred_at:
          type: "string"
          format: "date-time"
          description: "RFC 3339, UTC"
        reverses_adjustment_id:
          anyOf:
            - type: "string"
              format: "uuid"
            - type: "null"
        taxonomy_version:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
      required:
        - "object"
        - "id"
        - "charge_id"
        - "customer_id"
        - "direction"
        - "action"
        - "reason"
        - "category"
        - "origin"
        - "amount"
        - "consideration_effect"
        - "taxes"
        - "taxable_amount"
        - "currency"
        - "competence_month"
        - "accounting_month"
        - "occurred_at"
        - "reverses_adjustment_id"
        - "taxonomy_version"
      additionalProperties: false
    AdjustmentList:
      type: "object"
      properties:
        object:
          type: "string"
          const: "list"
        data:
          type: "array"
          items:
            "$ref": "#/components/schemas/Adjustment"
        has_more:
          type: "boolean"
          description: "There is a next page: ask again with starting_after = the id of the last item"
      required:
        - "object"
        - "data"
        - "has_more"
      additionalProperties: false
    Allocation:
      type: "object"
      properties:
        object:
          type: "string"
          const: "allocation"
        id:
          type: "string"
          format: "uuid"
        payment_id:
          type: "string"
          format: "uuid"
        charge_id:
          type: "string"
          format: "uuid"
        amount:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Signed"
        currency:
          type: "string"
          minLength: 3
          maxLength: 3
        consideration_effect:
          type: "string"
          const: "none"
      required:
        - "object"
        - "id"
        - "payment_id"
        - "charge_id"
        - "amount"
        - "consideration_effect"
      additionalProperties: false
    Payment:
      type: "object"
      properties:
        object:
          type: "string"
          const: "payment"
        id:
          type: "string"
          format: "uuid"
        customer_id:
          anyOf:
            - type: "string"
              format: "uuid"
            - type: "null"
        type:
          type: "string"
          enum:
            - "payment"
            - "credit_applied"
            - "offset"
            - "refund"
            - "moved_to_credit"
            - "reversal"
          description: "What happened to the money (open list)"
        amount:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "The money that really moved, signed: a refund or a reversal is negative, moved_to_credit is zero"
        currency:
          type: "string"
          minLength: 3
          maxLength: 3
        date:
          type: "string"
          format: "date"
          description: "YYYY-MM-DD"
        accounting_month:
          type: "string"
          pattern: "^\\d{4}-\\d{2}$"
          description: "YYYY-MM"
        method:
          type: "string"
          description: "cash, bank_transfer, pos, credit, compensazione, other (open list)"
        reference:
          anyOf:
            - type: "string"
            - type: "null"
        paid_by:
          anyOf:
            - type: "object"
              properties:
                kind:
                  anyOf:
                    - type: "string"
                    - type: "null"
                name:
                  anyOf:
                    - type: "string"
                    - type: "null"
                tax_code:
                  description: "customers.fiscal:read only"
                  anyOf:
                    - type: "string"
                    - type: "null"
                address_text:
                  description: "customers.fiscal:read only"
                  anyOf:
                    - type: "string"
                    - type: "null"
              required:
                - "kind"
                - "name"
              additionalProperties: false
            - type: "null"
          description: "Who paid on behalf of the customer (a parent): not a customer of its own"
        reverses_payment_id:
          anyOf:
            - type: "string"
              format: "uuid"
            - type: "null"
        action:
          anyOf:
            - type: "string"
            - type: "null"
          description: "Reversals only"
        reason:
          anyOf:
            - type: "string"
            - type: "null"
        category:
          anyOf:
            - type: "string"
            - type: "null"
        consideration_effect:
          type: "string"
          const: "none"
        allocations:
          type: "array"
          items:
            "$ref": "#/components/schemas/Allocation"
        taxonomy_version:
          anyOf:
            - type: "integer"
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: "null"
        created_at:
          type: "string"
          format: "date-time"
          description: "RFC 3339, UTC"
      required:
        - "object"
        - "id"
        - "customer_id"
        - "type"
        - "amount"
        - "currency"
        - "date"
        - "accounting_month"
        - "method"
        - "reference"
        - "paid_by"
        - "reverses_payment_id"
        - "action"
        - "reason"
        - "category"
        - "consideration_effect"
        - "allocations"
        - "taxonomy_version"
        - "created_at"
      additionalProperties: false
    PaymentList:
      type: "object"
      properties:
        object:
          type: "string"
          const: "list"
        data:
          type: "array"
          items:
            "$ref": "#/components/schemas/Payment"
        has_more:
          type: "boolean"
          description: "There is a next page: ask again with starting_after = the id of the last item"
      required:
        - "object"
        - "data"
        - "has_more"
      additionalProperties: false
    CreditEntry:
      type: "object"
      properties:
        object:
          type: "string"
          const: "credit_entry"
        id:
          type: "string"
          format: "uuid"
        customer_id:
          type: "string"
          format: "uuid"
        direction:
          type: "string"
          enum:
            - "credit"
            - "debit"
          description: "credit: the credit is born or grows; debit: it is used or refunded"
        amount:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Always positive: direction says the way"
        currency:
          type: "string"
          minLength: 3
          maxLength: 3
        source:
          type: "string"
          description: "Open list of codes"
        payment_id:
          anyOf:
            - type: "string"
              format: "uuid"
            - type: "null"
          description: "The movement that caused it"
        charge_id:
          anyOf:
            - type: "string"
              format: "uuid"
            - type: "null"
        action:
          anyOf:
            - type: "string"
            - type: "null"
        reason:
          anyOf:
            - type: "string"
            - type: "null"
        category:
          anyOf:
            - type: "string"
            - type: "null"
        reverses_entry_id:
          anyOf:
            - type: "string"
              format: "uuid"
            - type: "null"
        consideration_effect:
          type: "string"
          const: "none"
        created_at:
          type: "string"
          format: "date-time"
          description: "RFC 3339, UTC"
      required:
        - "object"
        - "id"
        - "customer_id"
        - "direction"
        - "amount"
        - "currency"
        - "source"
        - "payment_id"
        - "charge_id"
        - "action"
        - "reason"
        - "category"
        - "reverses_entry_id"
        - "consideration_effect"
        - "created_at"
      additionalProperties: false
    CreditEntryList:
      type: "object"
      properties:
        object:
          type: "string"
          const: "list"
        data:
          type: "array"
          items:
            "$ref": "#/components/schemas/CreditEntry"
        has_more:
          type: "boolean"
          description: "There is a next page: ask again with starting_after = the id of the last item"
      required:
        - "object"
        - "data"
        - "has_more"
      additionalProperties: false
    Receipt:
      type: "object"
      properties:
        object:
          type: "string"
          const: "receipt"
        id:
          type: "string"
          format: "uuid"
        kind:
          type: "string"
          enum:
            - "payment_receipt"
            - "refund_confirmation"
          description: "payment_receipt: series R, money received; refund_confirmation: series RB, money refunded (open list)"
        series:
          type: "string"
          description: "R, RB (open list): every series has its own progression"
        year:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
        sequence:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "Progressive number inside series and year, without gaps"
        number:
          type: "string"
          description: "The number as printed on the document"
        status:
          type: "string"
          enum:
            - "issued"
            - "voided"
          description: "A voided receipt stays, with its number"
        issued_at:
          type: "string"
          format: "date-time"
          description: "RFC 3339, UTC"
        voided_at:
          anyOf:
            - type: "string"
              format: "date-time"
              description: "RFC 3339, UTC"
            - type: "null"
        operation_type:
          anyOf:
            - type: "string"
            - type: "null"
          description: "Refund confirmations only: voluntary_refund, payment_reversal, chargeback (open list)"
        payment_id:
          anyOf:
            - type: "string"
              format: "uuid"
            - type: "null"
          description: "The payment, or the refund, that the receipt confirms"
        charge_id:
          anyOf:
            - type: "string"
              format: "uuid"
            - type: "null"
          description: "Only receipts of the old model, issued on a charge instead of a payment"
        customer_id:
          anyOf:
            - type: "string"
              format: "uuid"
            - type: "null"
        amount:
          anyOf:
            - type: "integer"
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: "Minor units of the currency (ISO 4217)"
            - type: "null"
          description: "As frozen on the document, signed: a refund confirmation is negative"
        currency:
          type: "string"
          minLength: 3
          maxLength: 3
        pdf_available:
          type: "boolean"
          description: "false only for the oldest receipts, issued before frozen documents: no sheet to print again"
        fiscal_document:
          type: "boolean"
          const: false
          description: "A confirmation of payment: the fiscal document is issued by your software"
      required:
        - "object"
        - "id"
        - "kind"
        - "series"
        - "year"
        - "sequence"
        - "number"
        - "status"
        - "issued_at"
        - "voided_at"
        - "operation_type"
        - "payment_id"
        - "charge_id"
        - "customer_id"
        - "amount"
        - "currency"
        - "pdf_available"
        - "fiscal_document"
      additionalProperties: false
    ReceiptList:
      type: "object"
      properties:
        object:
          type: "string"
          const: "list"
        data:
          type: "array"
          items:
            "$ref": "#/components/schemas/Receipt"
        has_more:
          type: "boolean"
          description: "There is a next page: ask again with starting_after = the id of the last item"
      required:
        - "object"
        - "data"
        - "has_more"
      additionalProperties: false
    Event:
      type: "object"
      properties:
        object:
          type: "string"
          const: "event"
        id:
          type: "string"
          format: "uuid"
          description: "Stable, unique across stables: use it to recognise an event you already processed"
        type:
          type: "string"
          description: "Open list: customer.updated, charge.created, charge.due_date_changed, charge.tax_changed, adjustment.created, payment.created, allocation.created, credit_entry.created, receipt.issued, receipt.voided"
        data:
          type: "object"
          properties:
            object:
              type: "string"
              description: "Open list: customer, charge, adjustment, payment, allocation, credit_entry, receipt"
            id:
              type: "string"
              format: "uuid"
            url:
              type: "string"
              description: "Where to read it, from the host: /api/v1/charges/{id}"
          required:
            - "object"
            - "id"
            - "url"
          additionalProperties: false
        occurred_at:
          type: "string"
          format: "date-time"
          description: "When the fact happened: its creation, issue or void time; for a tax change, its creation"
        recorded_at:
          type: "string"
          format: "date-time"
          description: "When the event was written: for historical events, the day the history was loaded"
        historical:
          type: "boolean"
          description: "true: a fact from before the events existed, loaded once, ordered by its date"
      required:
        - "object"
        - "id"
        - "type"
        - "data"
        - "occurred_at"
        - "recorded_at"
        - "historical"
      additionalProperties: false
    EventList:
      type: "object"
      properties:
        object:
          type: "string"
          const: "list"
        data:
          type: "array"
          items:
            "$ref": "#/components/schemas/Event"
        has_more:
          type: "boolean"
          description: "Ask again with after = next_cursor. A page can hold fewer events than limit, even none, while has_more is true"
        next_cursor:
          anyOf:
            - type: "string"
              format: "uuid"
            - type: "null"
          description: "Save it after processing the page, and pass it back as after. It can be the id of an event you are not shown. null only when the stable has no events for you yet"
      required:
        - "object"
        - "data"
        - "has_more"
        - "next_cursor"
      additionalProperties: false
    Codes:
      type: "object"
      properties:
        object:
          type: "string"
          const: "codes"
        language:
          type: "string"
          description: "The language of the names: ?lang=, then Accept-Language, then en"
        taxonomy_version:
          type: "integer"
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: "The taxonomy that action, reason and category come from"
        lists:
          type: "object"
          properties:
            charge_type:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
            action:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
            reason:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                      action:
                        type: "string"
                        description: "The name of a reason depends on its action: look it up with both"
                      category:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                      - "action"
                      - "category"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
            category:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
            origin:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
            payment_type:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
            payment_method:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
            credit_source:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
            receipt_kind:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
            refund_operation:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
            tax_category:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
              description: "UNCL 5305"
            unit:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
              description: "UNECE Rec. 20"
            event_type:
              type: "object"
              properties:
                fields:
                  type: "array"
                  items:
                    type: "string"
                  description: "Where these codes appear: resource.field"
                codes:
                  type: "array"
                  items:
                    type: "object"
                    properties:
                      code:
                        type: "string"
                      name:
                        type: "string"
                    required:
                      - "code"
                      - "name"
                    additionalProperties: false
              required:
                - "fields"
                - "codes"
              additionalProperties: false
          required:
            - "charge_type"
            - "action"
            - "reason"
            - "category"
            - "origin"
            - "payment_type"
            - "payment_method"
            - "credit_source"
            - "receipt_kind"
            - "refund_operation"
            - "tax_category"
            - "unit"
            - "event_type"
          additionalProperties: false
      required:
        - "object"
        - "language"
        - "taxonomy_version"
        - "lists"
      additionalProperties: false
