{
  "openapi": "3.1.1",
  "info": {
    "title": "Payclave Merchant API",
    "version": "1.0.0",
    "description": "Non-custodial stablecoin checkout. Funds move directly from customer to merchant wallets. This specification covers the core checkout, invoice, payment and webhook integration; the complete HTTP reference includes additional invoice actions, payment links, reconciliation and diagnostics. API major versions use URL prefixes (/v1). Compatible optional fields and new error codes may be added within v1; clients should tolerate them. Breaking contracts require a new major URL prefix. No v1 retirement is scheduled. Any future retirement must publish a migration guide and explicit retirement date before removal; deprecated operations will be marked deprecated in OpenAPI and responses will carry Deprecation (RFC 9745) and Sunset (RFC 8594) headers. No minimum support interval has been committed. See /api-policy.md.",
    "contact": {
      "url": "https://www.payclave.com/developers/docs"
    }
  },
  "servers": [
    {
      "url": "https://api.payclave.com"
    }
  ],
  "externalDocs": {
    "url": "https://www.payclave.com/developers/docs#api-reference",
    "description": "Complete HTTP reference"
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/v1/checkout-sessions": {
      "post": {
        "operationId": "createCheckoutSession",
        "summary": "POST /v1/checkout-sessions",
        "description": "Checkout creation and retrieval accept publishable or secret keys. Payment retrieval requires a secret key. Read amounts and payment status from the API before fulfillment.\n\nRequired: amount as a positive decimal string. Optional: externalReference. Secret keys may also send customerEmail, successUrl, cancelUrl, metadata, expiresInMinutes. Optional Idempotency-Key. Currency and settlement wallet come from the key's mode, not the request.\n\n201: checkout_session with id, checkoutId, invoiceId, invoiceNumber, checkoutUrl, mode, status, collectionState, amountDue, total, customerAmountPaid, customerAmountRemaining, currencyCode, chainId, tokenContract, settlementWalletAddress, expiresAt, createdAt. Persist these identifiers.",
        "tags": [
          "Checkout sessions and payments"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Reuse only for the same operation and payload when retrying.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Required: amount as a positive decimal string. Optional: externalReference. Secret keys may also send customerEmail, successUrl, cancelUrl, metadata, expiresInMinutes. Optional Idempotency-Key. Currency and settlement wallet come from the key's mode, not the request.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCheckoutSession"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "201: checkout_session with id, checkoutId, invoiceId, invoiceNumber, checkoutUrl, mode, status, collectionState, amountDue, total, customerAmountPaid, customerAmountRemaining, currencyCode, chainId, tokenContract, settlementWalletAddress, expiresAt, createdAt. Persist these identifiers.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/CreatedCheckoutSession"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/RequestMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "HTTP 400 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "HTTP 401 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "HTTP 403 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "HTTP 404 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "HTTP 409 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "HTTP 413 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "HTTP 422 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait at least Retry-After seconds before retrying.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Minimum delay in seconds before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "HTTP 500 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "HTTP 502 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "HTTP 503 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/checkout-sessions/{id}": {
      "get": {
        "operationId": "getCheckoutSession",
        "summary": "GET /v1/checkout-sessions/{id}",
        "description": "Checkout creation and retrieval accept publishable or secret keys. Payment retrieval requires a secret key. Read amounts and payment status from the API before fulfillment.\n\nPath: the returned checkout id. No body. There is no checkout-session list endpoint.\n\n200: current checkout_session, completedAt and latest paymentId/paymentStatus/transaction hashes when available. Secret-key reads add platformFee, netAmount, expectedMerchantSettlement, merchantAmountSettled, overpaymentAmount.",
        "tags": [
          "Checkout sessions and payments"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Path: the returned checkout id. No body. There is no checkout-session list endpoint.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200: current checkout_session, completedAt and latest paymentId/paymentStatus/transaction hashes when available. Secret-key reads add platformFee, netAmount, expectedMerchantSettlement, merchantAmountSettled, overpaymentAmount.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/CheckoutSession"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/RequestMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "HTTP 400 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "HTTP 401 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "HTTP 403 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "HTTP 404 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "HTTP 409 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "HTTP 413 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "HTTP 422 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait at least Retry-After seconds before retrying.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Minimum delay in seconds before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "HTTP 500 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "HTTP 502 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "HTTP 503 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/invoices": {
      "post": {
        "operationId": "createInvoice",
        "summary": "POST /v1/invoices",
        "description": "Secret key required. Itemized invoices use draft versioning. Collection actions do not transfer crypto or initiate refunds. Invoice creation and collection mutations may be unavailable until enabled for the merchant.\n\nItemized form: lines plus optional customer and invoice fields listed below. issue defaults to false; issue:true issues immediately. send:true requires issue:true and a customer email. Optional Idempotency-Key. The legacy amount-only form creates a payable invoice directly, not an itemized draft.\n\n201: invoice. An itemized draft has collectionState=draft and version; issuance returns invoiceNumber, hostedInvoiceUrl and checkout information. Use the returned id for subsequent operations.",
        "tags": [
          "Invoices"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Reuse only for the same operation and payload when retrying.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Itemized form: lines plus optional customer and invoice fields listed below. issue defaults to false; issue:true issues immediately. send:true requires issue:true and a customer email. Optional Idempotency-Key. The legacy amount-only form creates a payable invoice directly, not an itemized draft.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvoice"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "201: invoice. An itemized draft has collectionState=draft and version; issuance returns invoiceNumber, hostedInvoiceUrl and checkout information. Use the returned id for subsequent operations.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/Invoice"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/RequestMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "HTTP 400 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "HTTP 401 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "HTTP 403 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "HTTP 404 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "HTTP 409 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "HTTP 413 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "HTTP 422 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait at least Retry-After seconds before retrying.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Minimum delay in seconds before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "HTTP 500 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "HTTP 502 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "HTTP 503 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/invoices/{id}": {
      "get": {
        "operationId": "getInvoice",
        "summary": "GET /v1/invoices/{id}",
        "description": "Secret key required. Itemized invoices use draft versioning. Collection actions do not transfer crypto or initiate refunds. Invoice creation and collection mutations may be unavailable until enabled for the merchant.\n\nPath: invoice id or issued invoice number.\n\n200: invoice with line items, totals, collectionState, version, customer, checkoutSessions, payments and activity. Commercial fields and payment status have separate meanings.",
        "tags": [
          "Invoices"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Path: invoice id or issued invoice number.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200: invoice with line items, totals, collectionState, version, customer, checkoutSessions, payments and activity. Commercial fields and payment status have separate meanings.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/Invoice"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/RequestMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "HTTP 400 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "HTTP 401 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "HTTP 403 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "HTTP 404 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "HTTP 409 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "HTTP 413 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "HTTP 422 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait at least Retry-After seconds before retrying.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Minimum delay in seconds before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "HTTP 500 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "HTTP 502 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "HTTP 503 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/payments/{id}": {
      "get": {
        "operationId": "getPayment",
        "summary": "GET /v1/payments/{id}",
        "description": "Checkout creation and retrieval accept publishable or secret keys. Payment retrieval requires a secret key. Read amounts and payment status from the API before fulfillment.\n\nSecret key; path: paymentId from the invoice or checkout response. No body.\n\n200: payment record, including status, invoiceId, amountExpected, amountReceived, customerAmountCredited, merchantAmountSettled, transactionId, chainId, settlementWalletAddress, payer evidence, failureReason and confirmedAt. There is no general payment-list endpoint; use invoices or reconciliation for reporting.",
        "tags": [
          "Checkout sessions and payments"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Secret key; path: paymentId from the invoice or checkout response. No body.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200: payment record, including status, invoiceId, amountExpected, amountReceived, customerAmountCredited, merchantAmountSettled, transactionId, chainId, settlementWalletAddress, payer evidence, failureReason and confirmedAt. There is no general payment-list endpoint; use invoices or reconciliation for reporting.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/Payment"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/RequestMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "HTTP 400 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "HTTP 401 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "HTTP 403 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "HTTP 404 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "HTTP 409 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "HTTP 413 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "HTTP 422 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait at least Retry-After seconds before retrying.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Minimum delay in seconds before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "HTTP 500 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "HTTP 502 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "HTTP 503 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-endpoints": {
      "post": {
        "operationId": "createWebhookEndpoint",
        "summary": "POST /v1/webhook-endpoints",
        "description": "Secret key required. Endpoints, deliveries and signing secrets are mode-specific. The published server SDK 0.1.1 supports endpoint creation, synthetic tests and delivery listing only. Use HTTP for other webhook operations.\n\nJSON: url (required), eventTypes (optional array; omitted or empty subscribes to all supported types). This endpoint does not implement Idempotency-Key replay.\n\n201: endpoint, signingSecret and copyRequired. Store the secret securely; normal reads omit it. Avoid blindly retrying an uncertain creation; first list endpoints.",
        "tags": [
          "Webhook endpoints and deliveries"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "description": "JSON: url (required), eventTypes (optional array; omitted or empty subscribes to all supported types). This endpoint does not implement Idempotency-Key replay.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookEndpoint"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "201: endpoint, signingSecret and copyRequired. Store the secret securely; normal reads omit it. Avoid blindly retrying an uncertain creation; first list endpoints.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/RequestMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "HTTP 400 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "HTTP 401 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "HTTP 403 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "HTTP 404 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "HTTP 409 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "HTTP 413 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "HTTP 422 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait at least Retry-After seconds before retrying.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Minimum delay in seconds before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "HTTP 500 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "HTTP 502 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "HTTP 503 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/test": {
      "post": {
        "operationId": "createTestWebhook",
        "summary": "POST /v1/webhooks/test",
        "description": "Secret key required. Endpoints, deliveries and signing secrets are mode-specific. The published server SDK 0.1.1 supports endpoint creation, synthetic tests and delivery listing only. Use HTTP for other webhook operations.\n\nJSON: endpointId (required), eventType (optional; defaults to invoice.paid and must be subscribed). No idempotent replay.\n\n201: synthetic delivery whose event data contains test:true. This exercises delivery and signature handling, not onchain verification. Never fulfill an order from it.",
        "tags": [
          "Webhook endpoints and deliveries"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "description": "JSON: endpointId (required), eventType (optional; defaults to invoice.paid and must be subscribed). No idempotent replay.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTestWebhook"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "201: synthetic delivery whose event data contains test:true. This exercises delivery and signature handling, not onchain verification. Never fulfill an order from it.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/WebhookDelivery"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/RequestMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "HTTP 400 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "HTTP 401 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "HTTP 403 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "HTTP 404 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "HTTP 409 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "HTTP 413 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "HTTP 422 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait at least Retry-After seconds before retrying.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Minimum delay in seconds before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "HTTP 500 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "HTTP 502 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "HTTP 503 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-deliveries": {
      "get": {
        "operationId": "listWebhookDeliveries",
        "summary": "GET /v1/webhook-deliveries",
        "description": "Secret key required. Endpoints, deliveries and signing secrets are mode-specific. The published server SDK 0.1.1 supports endpoint creation, synthetic tests and delivery listing only. Use HTTP for other webhook operations.\n\nQuery: limit (default 25, maximum 100), endpointId, eventType, status, createdFrom, createdTo, replayStatus (original or replay), responseFamily (2xx, 3xx, 4xx, 5xx, network).\n\n200: data is an array of matching deliveries, newest first. No startingAfter cursor is supported.",
        "tags": [
          "Webhook endpoints and deliveries"
        ],
        "parameters": [
          {
            "name": "createdFrom",
            "in": "query",
            "required": false,
            "description": "Filter by createdFrom.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "createdTo",
            "in": "query",
            "required": false,
            "description": "Filter by createdTo.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "endpointId",
            "in": "query",
            "required": false,
            "description": "Filter by endpointId.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "eventType",
            "in": "query",
            "required": false,
            "description": "Filter by eventType.",
            "schema": {
              "$ref": "#/components/schemas/PayclaveWebhookEventType"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Filter by limit.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "replayStatus",
            "in": "query",
            "required": false,
            "description": "Filter by replayStatus.",
            "schema": {
              "enum": [
                "original",
                "replay"
              ],
              "type": "string"
            }
          },
          {
            "name": "responseFamily",
            "in": "query",
            "required": false,
            "description": "Filter by responseFamily.",
            "schema": {
              "enum": [
                "2xx",
                "3xx",
                "4xx",
                "5xx",
                "network"
              ],
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by status.",
            "schema": {
              "$ref": "#/components/schemas/PayclaveWebhookDeliveryStatus"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200: data is an array of matching deliveries, newest first. No startingAfter cursor is supported.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/RequestMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "HTTP 400 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "HTTP 401 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "HTTP 403 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "HTTP 404 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "HTTP 409 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "HTTP 413 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "HTTP 422 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait at least Retry-After seconds before retrying.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              },
              "Retry-After": {
                "description": "Minimum delay in seconds before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "HTTP 500 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "HTTP 502 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "HTTP 503 error. Inspect error.code and retain meta.requestId.",
            "headers": {
              "X-Request-Id": {
                "description": "Request correlation identifier.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit": {
                "description": "Present when a database quota is enforced. IETF draft-ietf-httpapi-ratelimit-headers-11 Structured Field list, e.g. \"quota-1\";r=19;t=30. r is remaining requests; t is seconds until reset. Multiple policies may apply. Failure-only quotas reserve a slot before responding and refund successful requests afterward.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Policy": {
                "description": "Applicable quota policy, e.g. \"quota-1\";q=20;w=60 (20 requests per 60 seconds). Policy names are response-local. No header means no advertised quota, not unlimited capacity.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Secret key sk_test_* or sk_live_*. Checkout creation/reads also accept pk_test_* or pk_live_*; publishable creation accepts amount and externalReference only."
      },
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Alternative to Authorization: Bearer. Test and live keys select separate data and wallet configuration."
      }
    },
    "schemas": {
      "CheckoutSession": {
        "$ref": "#/components/schemas/PayclaveCheckoutSession"
      },
      "CreateCheckoutSession": {
        "additionalProperties": false,
        "properties": {
          "amount": {
            "type": "string"
          },
          "cancelUrl": {
            "type": "string"
          },
          "customerEmail": {
            "type": "string"
          },
          "expiresInMinutes": {
            "type": "number"
          },
          "externalReference": {
            "type": "string"
          },
          "metadata": {
            "$ref": "#/components/schemas/PayclaveMetadata"
          },
          "successUrl": {
            "type": "string"
          }
        },
        "required": [
          "amount"
        ],
        "type": "object"
      },
      "CreateInvoice": {
        "anyOf": [
          {
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string"
              },
              "expiresInMinutes": {
                "type": "number"
              },
              "externalReference": {
                "type": "string"
              },
              "metadata": {
                "$ref": "#/components/schemas/PayclaveMetadata"
              }
            },
            "required": [
              "amount"
            ],
            "type": "object"
          },
          {
            "additionalProperties": false,
            "properties": {
              "cancelUrl": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "checkoutExpiresInMinutes": {
                "type": "number"
              },
              "currencyCode": {
                "type": "string"
              },
              "customer": {
                "$ref": "#/components/schemas/PayclaveInvoiceCustomer"
              },
              "discount": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/PayclaveInvoiceDiscountInput"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "dueAt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "externalReference": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "footer": {
                "type": "string"
              },
              "lines": {
                "items": {
                  "$ref": "#/components/schemas/PayclaveInvoiceLineInput"
                },
                "type": "array"
              },
              "memo": {
                "type": "string"
              },
              "metadata": {
                "$ref": "#/components/schemas/PayclaveMetadata"
              },
              "paymentTerms": {
                "type": "string"
              },
              "purchaseOrderNumber": {
                "type": "string"
              },
              "reminderSchedule": {
                "$ref": "#/components/schemas/PayclaveInvoiceReminderSchedule"
              },
              "successUrl": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "taxes": {
                "items": {
                  "$ref": "#/components/schemas/PayclaveInvoiceTaxInput"
                },
                "type": "array"
              }
            },
            "required": [
              "customer",
              "lines"
            ],
            "type": "object"
          }
        ]
      },
      "CreateTestWebhook": {
        "additionalProperties": false,
        "properties": {
          "endpointId": {
            "type": "string"
          },
          "eventType": {
            "$ref": "#/components/schemas/PayclaveWebhookEventType"
          }
        },
        "required": [
          "endpointId"
        ],
        "type": "object"
      },
      "CreateWebhookEndpoint": {
        "additionalProperties": false,
        "properties": {
          "eventTypes": {
            "items": {
              "$ref": "#/components/schemas/PayclaveWebhookEventType"
            },
            "type": "array"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "type": "object"
      },
      "CreatedCheckoutSession": {
        "$ref": "#/components/schemas/PayclaveCreatedCheckoutSession"
      },
      "Invoice": {
        "$ref": "#/components/schemas/PayclaveInvoice"
      },
      "PayclaveCheckoutSession": {
        "properties": {
          "amountDue": {
            "type": "string"
          },
          "amountReceived": {
            "type": "string"
          },
          "chainId": {
            "type": "number"
          },
          "checkoutId": {
            "type": "string"
          },
          "checkoutUrl": {
            "type": "string"
          },
          "collectionState": {
            "$ref": "#/components/schemas/PayclaveInvoiceCollectionState"
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "currencyCode": {
            "type": "string"
          },
          "customerAmountPaid": {
            "type": "string"
          },
          "customerAmountRemaining": {
            "type": "string"
          },
          "customerEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "expectedMerchantSettlement": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string"
          },
          "externalReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "invoiceId": {
            "type": [
              "string",
              "null"
            ]
          },
          "invoiceNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "merchantAmountSettled": {
            "type": "string"
          },
          "metadata": {
            "$ref": "#/components/schemas/PayclaveMetadata"
          },
          "mode": {
            "$ref": "#/components/schemas/PayclaveMode"
          },
          "netAmount": {
            "type": "string"
          },
          "object": {
            "const": "checkout_session",
            "type": "string"
          },
          "overpaymentAmount": {
            "type": "string"
          },
          "paymentId": {
            "description": "Present once a payment has been detected for the session.",
            "type": "string"
          },
          "paymentStatus": {
            "$ref": "#/components/schemas/PayclavePaymentStatus"
          },
          "platformFee": {
            "description": "Present on secret-key reads only: the merchant-absorbed platform fee and the net settlement (`amountDue` minus `platformFee`) the merchant receives.",
            "type": "string"
          },
          "settlementTxHash": {
            "type": "string"
          },
          "settlementWalletAddress": {
            "type": "string"
          },
          "sourceTxHash": {
            "type": "string"
          },
          "sourceType": {
            "$ref": "#/components/schemas/PayclaveSourceType"
          },
          "status": {
            "$ref": "#/components/schemas/PayclaveInvoiceStatus"
          },
          "tokenContract": {
            "type": "string"
          },
          "tokenSymbol": {
            "type": "string"
          },
          "total": {
            "type": "string"
          },
          "txHash": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "checkoutId",
          "object",
          "mode",
          "status",
          "collectionState",
          "invoiceId",
          "invoiceNumber",
          "amountDue",
          "amountReceived",
          "total",
          "customerAmountPaid",
          "customerAmountRemaining",
          "currencyCode",
          "chainId",
          "tokenSymbol",
          "tokenContract",
          "settlementWalletAddress",
          "externalReference",
          "customerEmail",
          "metadata",
          "checkoutUrl",
          "expiresAt",
          "completedAt",
          "createdAt"
        ],
        "type": "object"
      },
      "PayclaveCreatedCheckoutSession": {
        "properties": {
          "amountDue": {
            "type": "string"
          },
          "amountReceived": {
            "type": "string"
          },
          "chainId": {
            "type": "number"
          },
          "checkoutId": {
            "type": "string"
          },
          "checkoutUrl": {
            "type": "string"
          },
          "collectionState": {
            "$ref": "#/components/schemas/PayclaveInvoiceCollectionState"
          },
          "createdAt": {
            "type": "string"
          },
          "currencyCode": {
            "type": "string"
          },
          "customerAmountPaid": {
            "type": "string"
          },
          "customerAmountRemaining": {
            "type": "string"
          },
          "customerEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "expiresAt": {
            "type": "string"
          },
          "externalReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "invoiceId": {
            "type": "string"
          },
          "invoiceNumber": {
            "type": "string"
          },
          "metadata": {
            "$ref": "#/components/schemas/PayclaveMetadata"
          },
          "mode": {
            "$ref": "#/components/schemas/PayclaveMode"
          },
          "object": {
            "const": "checkout_session",
            "type": "string"
          },
          "settlementWalletAddress": {
            "type": "string"
          },
          "sourceType": {
            "$ref": "#/components/schemas/PayclaveSourceType"
          },
          "status": {
            "const": "pending",
            "type": "string"
          },
          "tokenContract": {
            "type": "string"
          },
          "tokenSymbol": {
            "type": "string"
          },
          "total": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "checkoutId",
          "object",
          "mode",
          "status",
          "collectionState",
          "invoiceId",
          "invoiceNumber",
          "amountDue",
          "amountReceived",
          "total",
          "customerAmountPaid",
          "customerAmountRemaining",
          "currencyCode",
          "chainId",
          "tokenSymbol",
          "tokenContract",
          "settlementWalletAddress",
          "externalReference",
          "customerEmail",
          "metadata",
          "checkoutUrl",
          "expiresAt",
          "createdAt"
        ],
        "type": "object"
      },
      "PayclaveInvoice": {
        "properties": {
          "activity": {
            "items": {
              "$ref": "#/components/schemas/PayclaveInvoiceActivityEvent"
            },
            "type": "array"
          },
          "adjustments": {
            "items": {
              "$ref": "#/components/schemas/PayclavePaymentAdjustment"
            },
            "type": "array"
          },
          "amountDue": {
            "type": "string"
          },
          "amountReceived": {
            "type": "string"
          },
          "calculationVersion": {
            "type": "string"
          },
          "cancelledAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "chainId": {
            "type": "number"
          },
          "checkoutSessions": {
            "items": {
              "$ref": "#/components/schemas/PayclaveInvoiceCheckoutSession"
            },
            "type": "array"
          },
          "collectionState": {
            "$ref": "#/components/schemas/PayclaveInvoiceCollectionState"
          },
          "createdAt": {
            "type": "string"
          },
          "currencyCode": {
            "type": "string"
          },
          "customer": {
            "$ref": "#/components/schemas/PayclaveInvoiceCustomer"
          },
          "customerAmountPaid": {
            "type": "string"
          },
          "customerAmountRemaining": {
            "type": "string"
          },
          "deliveries": {
            "items": {
              "$ref": "#/components/schemas/PayclaveInvoiceDelivery"
            },
            "type": "array"
          },
          "discount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PayclaveInvoiceDiscountInput"
              },
              {
                "type": "null"
              }
            ]
          },
          "discountTotal": {
            "type": "string"
          },
          "dueAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "expectedMerchantSettlement": {
            "type": "string"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "externalReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "footer": {
            "type": "string"
          },
          "hostedInvoiceEnabled": {
            "type": "boolean"
          },
          "hostedInvoiceUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "internalId": {
            "type": "string"
          },
          "invoiceNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "issuedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastActivityAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastReminderAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastSentAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lines": {
            "items": {
              "additionalProperties": false,
              "properties": {
                "description": {
                  "type": "string"
                },
                "id": {
                  "type": "string"
                },
                "lineTotal": {
                  "type": "string"
                },
                "quantity": {
                  "type": "string"
                },
                "sku": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "unitAmount": {
                  "type": "string"
                }
              },
              "required": [
                "description",
                "lineTotal",
                "quantity",
                "unitAmount"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "memo": {
            "type": "string"
          },
          "merchantAmountSettled": {
            "type": "string"
          },
          "metadata": {
            "$ref": "#/components/schemas/PayclaveMetadata"
          },
          "migrationState": {
            "$ref": "#/components/schemas/PayclaveMigrationState"
          },
          "mode": {
            "$ref": "#/components/schemas/PayclaveMode"
          },
          "netAmount": {
            "type": "string"
          },
          "nextReminderAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "object": {
            "const": "invoice",
            "type": "string"
          },
          "overpaymentAmount": {
            "type": "string"
          },
          "paidAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentTerms": {
            "type": "string"
          },
          "payments": {
            "items": {
              "$ref": "#/components/schemas/PayclaveInvoicePayment"
            },
            "type": "array"
          },
          "platformFee": {
            "type": "string"
          },
          "publicToken": {
            "type": [
              "string",
              "null"
            ]
          },
          "purchaseOrderNumber": {
            "type": "string"
          },
          "reminderSchedule": {
            "$ref": "#/components/schemas/PayclaveInvoiceReminderSchedule"
          },
          "remindersPausedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "sellerSnapshot": {
            "anyOf": [
              {
                "additionalProperties": false,
                "properties": {
                  "address": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "businessEmail": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "displayName": {
                    "type": "string"
                  },
                  "taxIdentifier": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "displayName"
                ],
                "type": "object"
              },
              {
                "type": "null"
              }
            ]
          },
          "settlementWalletAddress": {
            "type": "string"
          },
          "sourceType": {
            "$ref": "#/components/schemas/PayclaveSourceType"
          },
          "status": {
            "$ref": "#/components/schemas/PayclaveInvoiceStatus"
          },
          "subtotal": {
            "type": "string"
          },
          "taxTotal": {
            "type": "string"
          },
          "taxes": {
            "items": {
              "$ref": "#/components/schemas/PayclaveInvoiceTaxInput"
            },
            "type": "array"
          },
          "tokenContract": {
            "type": "string"
          },
          "total": {
            "type": "string"
          },
          "uncollectibleAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "updatedAt": {
            "type": "string"
          },
          "version": {
            "type": "number"
          },
          "voidedAt": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "invoiceNumber",
          "object",
          "mode",
          "status",
          "collectionState",
          "subtotal",
          "discountTotal",
          "taxTotal",
          "total",
          "customerAmountPaid",
          "customerAmountRemaining",
          "expectedMerchantSettlement",
          "merchantAmountSettled",
          "overpaymentAmount",
          "migrationState",
          "amountDue",
          "amountReceived",
          "platformFee",
          "netAmount",
          "currencyCode",
          "chainId",
          "tokenContract",
          "settlementWalletAddress",
          "externalReference",
          "metadata",
          "expiresAt",
          "paidAt",
          "cancelledAt",
          "createdAt"
        ],
        "type": "object"
      },
      "PayclaveInvoiceActivityEvent": {
        "properties": {
          "action": {
            "type": "string"
          },
          "actorId": {
            "type": "string"
          },
          "actorType": {
            "type": "string"
          },
          "changes": {
            "additionalProperties": {},
            "type": "object"
          },
          "createdAt": {
            "type": "string"
          },
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "action",
          "actorType",
          "actorId",
          "changes",
          "createdAt"
        ],
        "type": "object"
      },
      "PayclaveInvoiceCheckoutSession": {
        "properties": {
          "amountDue": {
            "type": "string"
          },
          "checkoutId": {
            "type": "string"
          },
          "checkoutUrl": {
            "type": "string"
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "sourceType": {
            "$ref": "#/components/schemas/PayclaveSourceType"
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "checkoutId",
          "status",
          "amountDue",
          "checkoutUrl",
          "expiresAt",
          "completedAt",
          "createdAt"
        ],
        "type": "object"
      },
      "PayclaveInvoiceCollectionState": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "draft",
              "open",
              "past_due",
              "partially_paid",
              "paid",
              "void",
              "uncollectible"
            ],
            "type": "string"
          }
        ]
      },
      "PayclaveInvoiceCustomer": {
        "properties": {
          "billingAddress": {
            "type": [
              "string",
              "null"
            ]
          },
          "company": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PayclaveInvoiceDelivery": {
        "properties": {
          "createdAt": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ]
          },
          "providerMessageId": {
            "type": [
              "string",
              "null"
            ]
          },
          "recipient": {
            "type": "string"
          },
          "reminderKey": {
            "type": [
              "string",
              "null"
            ]
          },
          "scheduledFor": {
            "type": "string"
          },
          "sentAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "templateVersion": {
            "type": "string"
          },
          "type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "enum": [
                  "issue",
                  "send",
                  "reminder"
                ],
                "type": "string"
              }
            ]
          }
        },
        "required": [
          "id",
          "type",
          "recipient",
          "templateVersion",
          "status",
          "providerMessageId",
          "lastError",
          "scheduledFor",
          "sentAt",
          "createdAt",
          "reminderKey"
        ],
        "type": "object"
      },
      "PayclaveInvoiceDiscountInput": {
        "anyOf": [
          {
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string"
              },
              "type": {
                "const": "fixed",
                "type": "string"
              }
            },
            "required": [
              "type",
              "amount"
            ],
            "type": "object"
          },
          {
            "additionalProperties": false,
            "properties": {
              "percentage": {
                "type": "string"
              },
              "type": {
                "const": "percentage",
                "type": "string"
              }
            },
            "required": [
              "type",
              "percentage"
            ],
            "type": "object"
          }
        ]
      },
      "PayclaveInvoiceLineInput": {
        "properties": {
          "description": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "quantity": {
            "type": "string"
          },
          "sku": {
            "type": [
              "string",
              "null"
            ]
          },
          "unitAmount": {
            "type": "string"
          }
        },
        "required": [
          "description",
          "quantity",
          "unitAmount"
        ],
        "type": "object"
      },
      "PayclaveInvoicePayment": {
        "properties": {
          "amountExpected": {
            "type": "string"
          },
          "amountReceived": {
            "type": "string"
          },
          "chainId": {
            "type": "number"
          },
          "checkoutSessionId": {
            "type": "string"
          },
          "confirmedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "customerAmountCredited": {
            "type": "string"
          },
          "customerAmountTendered": {
            "type": "string"
          },
          "expectedMerchantSettlement": {
            "type": "string"
          },
          "failureReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "invoiceId": {
            "type": "string"
          },
          "merchantAmountSettled": {
            "type": "string"
          },
          "mode": {
            "$ref": "#/components/schemas/PayclaveMode"
          },
          "netAmount": {
            "type": "string"
          },
          "platformFee": {
            "type": "string"
          },
          "platformFeeCollected": {
            "type": "string"
          },
          "platformFeeExpected": {
            "type": "string"
          },
          "settlementTransactionId": {
            "type": [
              "string",
              "null"
            ]
          },
          "settlementWalletAddress": {
            "type": "string"
          },
          "sourceTransactionId": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/PayclavePaymentStatus"
          },
          "transactionId": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "invoiceId",
          "transactionId",
          "sourceTransactionId",
          "settlementTransactionId",
          "mode",
          "status",
          "amountExpected",
          "amountReceived",
          "platformFee",
          "netAmount",
          "chainId",
          "settlementWalletAddress",
          "failureReason",
          "confirmedAt",
          "createdAt"
        ],
        "type": "object"
      },
      "PayclaveInvoiceReminderSchedule": {
        "properties": {
          "daysAfterDue": {
            "items": {
              "type": "number"
            },
            "type": "array"
          },
          "daysBeforeDue": {
            "items": {
              "type": "number"
            },
            "type": "array"
          },
          "enabled": {
            "type": "boolean"
          },
          "onDue": {
            "type": "boolean"
          }
        },
        "required": [
          "enabled"
        ],
        "type": "object"
      },
      "PayclaveInvoiceStatus": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "pending",
              "processing",
              "paid",
              "underpaid",
              "overpaid",
              "expired",
              "failed",
              "cancelled"
            ],
            "type": "string"
          }
        ]
      },
      "PayclaveInvoiceTaxInput": {
        "properties": {
          "amount": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "jurisdiction": {
            "type": [
              "string",
              "null"
            ]
          },
          "label": {
            "type": "string"
          },
          "registrationReference": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "label",
          "amount"
        ],
        "type": "object"
      },
      "PayclaveMetadata": {
        "type": "object"
      },
      "PayclaveMigrationState": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "current",
              "review_required"
            ],
            "type": "string"
          }
        ]
      },
      "PayclaveMode": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "test",
              "live"
            ],
            "type": "string"
          }
        ]
      },
      "PayclavePayment": {
        "properties": {
          "amountExpected": {
            "type": "string"
          },
          "amountReceived": {
            "type": "string"
          },
          "chainId": {
            "type": "number"
          },
          "confirmedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "creditEvidenceType": {
            "type": "string"
          },
          "customerAmountCredited": {
            "type": "string"
          },
          "customerAmountTendered": {
            "type": "string"
          },
          "expectedMerchantSettlement": {
            "type": "string"
          },
          "failureReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "invoiceId": {
            "type": "string"
          },
          "invoiceNumber": {
            "type": "string"
          },
          "merchantAmountSettled": {
            "type": "string"
          },
          "migrationState": {
            "$ref": "#/components/schemas/PayclaveMigrationState"
          },
          "mode": {
            "$ref": "#/components/schemas/PayclaveMode"
          },
          "netAmount": {
            "type": "string"
          },
          "object": {
            "const": "payment",
            "type": "string"
          },
          "payerWalletAddress": {
            "type": "string"
          },
          "payerWalletEvidence": {
            "type": "string"
          },
          "platformFee": {
            "type": "string"
          },
          "platformFeeCollected": {
            "type": "string"
          },
          "platformFeeExpected": {
            "type": "string"
          },
          "settlementWalletAddress": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/PayclavePaymentStatus"
          },
          "transactionId": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "object",
          "invoiceId",
          "invoiceNumber",
          "transactionId",
          "mode",
          "status",
          "amountExpected",
          "amountReceived",
          "customerAmountTendered",
          "customerAmountCredited",
          "expectedMerchantSettlement",
          "merchantAmountSettled",
          "platformFeeExpected",
          "platformFeeCollected",
          "payerWalletAddress",
          "payerWalletEvidence",
          "creditEvidenceType",
          "migrationState",
          "platformFee",
          "netAmount",
          "chainId",
          "settlementWalletAddress",
          "failureReason",
          "confirmedAt",
          "createdAt"
        ],
        "type": "object"
      },
      "PayclavePaymentAdjustment": {
        "properties": {
          "amount": {
            "type": "string"
          },
          "chainId": {
            "type": "number"
          },
          "createdAt": {
            "type": "string"
          },
          "createdById": {
            "type": "string"
          },
          "createdByType": {
            "type": "string"
          },
          "externalTransactionHash": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "invoiceId": {
            "type": "string"
          },
          "merchantId": {
            "type": "string"
          },
          "mode": {
            "$ref": "#/components/schemas/PayclaveMode"
          },
          "paymentId": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "tokenContract": {
            "type": "string"
          },
          "type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "enum": [
                  "refund_reference",
                  "write_off",
                  "correction"
                ],
                "type": "string"
              }
            ]
          }
        },
        "required": [
          "id",
          "merchantId",
          "mode",
          "invoiceId",
          "type",
          "amount",
          "reason",
          "createdByType",
          "createdById",
          "createdAt"
        ],
        "type": "object"
      },
      "PayclavePaymentStatus": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "detected",
              "validating",
              "confirmed",
              "failed",
              "duplicate",
              "underpaid",
              "overpaid"
            ],
            "type": "string"
          }
        ]
      },
      "PayclaveSourceType": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "api",
              "dashboard",
              "payment_link",
              "sdk",
              "legacy"
            ],
            "type": "string"
          }
        ]
      },
      "PayclaveWebhookData": {
        "type": "object"
      },
      "PayclaveWebhookDelivery": {
        "properties": {
          "attemptCount": {
            "type": "number"
          },
          "attempts": {
            "items": {
              "$ref": "#/components/schemas/PayclaveWebhookDeliveryAttempt"
            },
            "type": "array"
          },
          "createdAt": {
            "type": "string"
          },
          "deliveredAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "endpointId": {
            "type": "string"
          },
          "eventId": {
            "type": "string"
          },
          "eventType": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PayclaveWebhookEventType"
              },
              {
                "type": "string"
              }
            ]
          },
          "id": {
            "type": "string"
          },
          "idempotencyKey": {
            "type": "string"
          },
          "invoiceId": {
            "type": [
              "string",
              "null"
            ]
          },
          "latestAttempt": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PayclaveWebhookDeliveryAttemptSummary"
              },
              {
                "type": "null"
              }
            ]
          },
          "latestErrorCategory": {
            "type": [
              "string",
              "null"
            ]
          },
          "nextAttemptAt": {
            "type": "string"
          },
          "object": {
            "const": "webhook_delivery",
            "type": "string"
          },
          "payload": {
            "$ref": "#/components/schemas/PayclaveWebhookEvent"
          },
          "replayOfDeliveryId": {
            "type": [
              "string",
              "null"
            ]
          },
          "replayRootDeliveryId": {
            "type": [
              "string",
              "null"
            ]
          },
          "replayedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "replayedBy": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/PayclaveWebhookDeliveryStatus"
          }
        },
        "required": [
          "id",
          "object",
          "endpointId",
          "invoiceId",
          "eventId",
          "eventType",
          "status",
          "idempotencyKey",
          "payload",
          "nextAttemptAt",
          "deliveredAt",
          "attemptCount",
          "latestAttempt",
          "replayOfDeliveryId",
          "replayRootDeliveryId",
          "replayedBy",
          "replayedAt",
          "createdAt"
        ],
        "type": "object"
      },
      "PayclaveWebhookDeliveryAttempt": {
        "properties": {
          "attemptNumber": {
            "type": "number"
          },
          "attemptedAt": {
            "type": "string"
          },
          "completedAt": {
            "type": "string"
          },
          "destinationHost": {
            "type": "string"
          },
          "durationMs": {
            "type": "number"
          },
          "errorCategory": {
            "type": [
              "string",
              "null"
            ]
          },
          "errorMessage": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "requestHeaders": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ]
          },
          "responseBody": {
            "type": [
              "string",
              "null"
            ]
          },
          "responseBodyTruncated": {
            "type": "boolean"
          },
          "responseHeaders": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ]
          },
          "responseStatusCode": {
            "type": [
              "number",
              "null"
            ]
          },
          "sanitizedAt": {
            "type": "string"
          },
          "startedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "attemptNumber",
          "responseStatusCode",
          "responseBody",
          "responseBodyTruncated",
          "errorMessage",
          "attemptedAt",
          "startedAt",
          "completedAt",
          "durationMs"
        ],
        "type": "object"
      },
      "PayclaveWebhookDeliveryAttemptSummary": {
        "properties": {
          "attemptedAt": {
            "type": "string"
          },
          "errorCategory": {
            "type": [
              "string",
              "null"
            ]
          },
          "errorMessage": {
            "type": [
              "string",
              "null"
            ]
          },
          "responseStatusCode": {
            "type": [
              "number",
              "null"
            ]
          }
        },
        "required": [
          "responseStatusCode",
          "errorMessage",
          "attemptedAt"
        ],
        "type": "object"
      },
      "PayclaveWebhookDeliveryStatus": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "pending",
              "delivering",
              "delivered",
              "retry_scheduled",
              "failed"
            ],
            "type": "string"
          }
        ]
      },
      "PayclaveWebhookEndpoint": {
        "properties": {
          "copyRequired": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string"
          },
          "currentSecretVersion": {
            "type": "number"
          },
          "enabled": {
            "type": "boolean"
          },
          "eventTypes": {
            "items": {
              "$ref": "#/components/schemas/PayclaveWebhookEventType"
            },
            "type": "array"
          },
          "id": {
            "type": "string"
          },
          "mode": {
            "$ref": "#/components/schemas/PayclaveMode"
          },
          "object": {
            "const": "webhook_endpoint",
            "type": "string"
          },
          "secretOverlap": {
            "additionalProperties": false,
            "properties": {
              "expiresAt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "previousVersion": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "status": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "enum": [
                      "none",
                      "active"
                    ],
                    "type": "string"
                  }
                ]
              }
            },
            "required": [
              "status",
              "expiresAt",
              "previousVersion"
            ],
            "type": "object"
          },
          "secretVersions": {
            "items": {
              "$ref": "#/components/schemas/PayclaveWebhookSecretVersion"
            },
            "type": "array"
          },
          "signingSecret": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "object",
          "mode",
          "url",
          "enabled",
          "eventTypes",
          "currentSecretVersion",
          "secretVersions",
          "secretOverlap",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "PayclaveWebhookEvent": {
        "properties": {
          "createdAt": {
            "type": "string"
          },
          "data": {
            "$ref": "#/components/schemas/PayclaveWebhookData"
          },
          "id": {
            "type": "string"
          },
          "mode": {
            "$ref": "#/components/schemas/PayclaveMode"
          },
          "object": {
            "const": "event",
            "type": "string"
          },
          "type": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PayclaveWebhookEventType"
              },
              {
                "type": "string"
              }
            ]
          }
        },
        "required": [
          "id",
          "object",
          "type",
          "mode",
          "createdAt",
          "data"
        ],
        "type": "object"
      },
      "PayclaveWebhookEventType": {
        "enum": [
          "invoice.issued",
          "invoice.paid",
          "invoice.partially_paid",
          "invoice.past_due",
          "invoice.overpaid",
          "invoice.voided",
          "invoice.uncollectible",
          "invoice.refund_recorded",
          "invoice.payment_received_after_void",
          "invoice.payment_received_after_uncollectible",
          "invoice.expired",
          "payment_link.completed",
          "payment_link.expired",
          "payment.failed",
          "payment.underpaid",
          "payment.overpaid"
        ],
        "type": "string"
      },
      "PayclaveWebhookSecretVersion": {
        "properties": {
          "activatesAt": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "revokedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "testedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "version": {
            "type": "number"
          }
        },
        "required": [
          "version",
          "createdAt",
          "activatesAt",
          "expiresAt",
          "revokedAt",
          "testedAt"
        ],
        "type": "object"
      },
      "Payment": {
        "$ref": "#/components/schemas/PayclavePayment"
      },
      "WebhookDelivery": {
        "$ref": "#/components/schemas/PayclaveWebhookDelivery"
      },
      "WebhookEndpoint": {
        "$ref": "#/components/schemas/PayclaveWebhookEndpoint"
      },
      "RequestMeta": {
        "type": "object",
        "required": [
          "requestId"
        ],
        "properties": {
          "requestId": {
            "type": "string",
            "description": "Support correlation identifier, also returned in X-Request-Id."
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "success",
          "error",
          "meta"
        ],
        "properties": {
          "success": {
            "const": false
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable error code. Handle unknown future codes by HTTP status.",
                "examples": [
                  "VALIDATION_ERROR",
                  "INVALID_API_KEY",
                  "RATE_LIMIT_EXCEEDED"
                ]
              },
              "message": {
                "type": "string"
              },
              "details": {
                "description": "Optional error-specific JSON context."
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/RequestMeta"
          }
        }
      }
    }
  }
}
