{
  "openapi": "3.1.0",
  "info": {
    "title": "Invoise integration API",
    "version": "2026-09-23",
    "description": "Public integration operations for merchants and payment agents. Dashboard sign-in, wallet authentication, and internal administrative routes are documented separately or excluded.\n\nExamples use fictional network and token values. Read the current catalogue from GET /networks and merchant availability from GET /merchants/{merchant_id}/networks before creating invoices or deposits."
  },
  "servers": [
    {
      "url": "https://platform.invoise.me/api/v1",
      "description": "Public API v1"
    }
  ],
  "tags": [
    {
      "name": "Public",
      "description": "Unauthenticated catalog, checkout, asset, and liveness routes."
    },
    {
      "name": "Account",
      "description": "Compact account and profile endpoints. Sign-in ceremonies live in their dedicated references."
    },
    {
      "name": "Merchants and team",
      "description": "Merchant discovery, shop creation, grants, invites, and team administration."
    },
    {
      "name": "Shops",
      "description": "Shop settings, terms, branding, metrics, and CSV export."
    },
    {
      "name": "Invoices and deposits",
      "description": "Create and monitor fixed invoices and free-amount deposits."
    },
    {
      "name": "API keys",
      "description": "Create, scope, allowlist, disable, and revoke shop keys."
    },
    {
      "name": "Webhooks",
      "description": "Register endpoints, inspect deliveries, and replay stored envelopes."
    },
    {
      "name": "Sandbox",
      "description": "Drive simulated payment events and reset test financial state."
    }
  ],
  "paths": {
    "/networks": {
      "get": {
        "operationId": "listNetworks",
        "summary": "List available networks and tokens",
        "description": "Returns the public integration catalog, EVM, Solana and Tron networks alike (family). Use the returned chain IDs, token addresses, and decimals when creating invoices or deposits, and minimum_payment as the smallest invoice amount.\n\nAuthentication: None.\n\nScope: Not applicable.",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Only enabled networks with at least one ready token are returned. minimum_payment is the smallest invoice amount on that network, in whole tokens.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Network"
                  }
                },
                "example": [
                  {
                    "chain_id": 12345,
                    "name": "Example network",
                    "native_symbol": "COIN",
                    "explorer_url": "https://explorer.example",
                    "main_factory": "0x1111111111111111111111111111111111111111",
                    "invoice_factory": "0x2222222222222222222222222222222222222222",
                    "start_block": 12000000,
                    "tokens": [
                      {
                        "address": "0x6666666666666666666666666666666666666666",
                        "symbol": "TOKEN",
                        "decimals": 6
                      }
                    ],
                    "minimum_payment": "1"
                  }
                ]
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "x-auth": {
          "kind": "public",
          "apiKeyScopes": []
        }
      }
    },
    "/checkout/{public_id}": {
      "get": {
        "operationId": "getCheckout",
        "summary": "Read a public checkout",
        "description": "No authentication is required. The response is safe to expose to a hosted payment page. Use payment_url from the response when redirecting a payer.\n\nAuthentication: None.\n\nScope: Not applicable.",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "The public checkout state. received is cumulative confirmed incoming amount in base units. A group returns group: true and one complete checkout per option.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/Checkout"
                    },
                    {
                      "$ref": "#/components/schemas/CheckoutGroup"
                    }
                  ]
                },
                "examples": {
                  "example1": {
                    "value": {
                      "public_id": "pay_7Jm2Qp8K4dR6sT9v",
                      "shop_id": "11111111-1111-4111-8111-111111111111",
                      "kind": "invoice",
                      "family": "evm",
                      "chain_id": 12345,
                      "token": "0x6666666666666666666666666666666666666666",
                      "token_decimals": 6,
                      "network": {
                        "chain_id": 12345,
                        "name": "Example network",
                        "native_symbol": "COIN",
                        "explorer_url": "https://explorer.example",
                        "main_factory": "0x1111111111111111111111111111111111111111",
                        "invoice_factory": "0x2222222222222222222222222222222222222222",
                        "start_block": 12000000,
                        "tokens": [
                          {
                            "address": "0x6666666666666666666666666666666666666666",
                            "symbol": "TOKEN",
                            "decimals": 6
                          }
                        ],
                        "minimum_payment": "1"
                      },
                      "amount": "10000000",
                      "address": "0x3333333333333333333333333333333333333333",
                      "status": "open",
                      "cancelled_at": null,
                      "disabled_at": null,
                      "expires_at": "2026-10-19T09:00:00Z",
                      "description": "Order 1042",
                      "return_url": "https://merchant.example/paid",
                      "branding": {
                        "name": "Demo shop"
                      },
                      "merchant_name": "Demo merchant",
                      "sandbox": false,
                      "tx_hash": "",
                      "received": "0",
                      "payment_url": "https://pay.invoise.me/pay_7Jm2Qp8K4dR6sT9v"
                    }
                  },
                  "example2": {
                    "value": {
                      "group": true,
                      "public_id": "pay_9Tq3Wm5Rz8Kd2YpL",
                      "shop_id": "11111111-1111-4111-8111-111111111111",
                      "kind": "invoice",
                      "amount": "10",
                      "status": "open",
                      "cancelled_at": null,
                      "disabled_at": null,
                      "expires_at": "2026-10-19T09:00:00Z",
                      "description": "Order 1043",
                      "return_url": "https://merchant.example/paid",
                      "branding": {
                        "name": "Demo shop"
                      },
                      "merchant_name": "Demo merchant",
                      "sandbox": false,
                      "paid_public_id": null,
                      "payment_url": "https://pay.invoise.me/pay_9Tq3Wm5Rz8Kd2YpL",
                      "options": [
                        {
                          "public_id": "pay_7Jm2Qp8K4dR6sT9v",
                          "shop_id": "11111111-1111-4111-8111-111111111111",
                          "kind": "invoice",
                          "family": "evm",
                          "chain_id": 12345,
                          "token": "0x6666666666666666666666666666666666666666",
                          "token_decimals": 6,
                          "network": {
                            "chain_id": 12345,
                            "name": "Example network",
                            "native_symbol": "COIN",
                            "explorer_url": "https://explorer.example",
                            "main_factory": "0x1111111111111111111111111111111111111111",
                            "invoice_factory": "0x2222222222222222222222222222222222222222",
                            "start_block": 12000000,
                            "tokens": [
                              {
                                "address": "0x6666666666666666666666666666666666666666",
                                "symbol": "TOKEN",
                                "decimals": 6
                              }
                            ],
                            "minimum_payment": "1"
                          },
                          "amount": "10000000",
                          "address": "0x3333333333333333333333333333333333333333",
                          "status": "open",
                          "cancelled_at": null,
                          "disabled_at": null,
                          "expires_at": "2026-10-19T09:00:00Z",
                          "description": "Order 1042",
                          "return_url": "https://merchant.example/paid",
                          "branding": {
                            "name": "Demo shop"
                          },
                          "merchant_name": "Demo merchant",
                          "sandbox": false,
                          "tx_hash": "",
                          "received": "0"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "not_found: The requested resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "not_found",
                    "message": "not_found"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "public_id",
            "required": true,
            "description": "Public payment identifier returned by an issuance request.",
            "schema": {
              "type": "string"
            },
            "example": "pay_7Jm2Qp8K4dR6sT9v"
          }
        ],
        "x-auth": {
          "kind": "public",
          "apiKeyScopes": []
        }
      }
    },
    "/assets/{id}": {
      "get": {
        "operationId": "getBrandingAsset",
        "summary": "Fetch a branding asset",
        "description": "Returns the immutable PNG asset referenced by shop branding. Cache the response according to its immutable cache headers.\n\nAuthentication: None.\n\nScope: Not applicable.",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "PNG bytes. The success response is binary; JSON errors use the standard error envelope.",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "x-json-error-example": {
              "error": {
                "code": "not_found",
                "message": "not_found"
              }
            }
          },
          "404": {
            "description": "not_found: The requested resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "not_found",
                    "message": "not_found"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "Branding asset UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "44444444-4444-4444-8444-444444444444"
          }
        ],
        "x-auth": {
          "kind": "public",
          "apiKeyScopes": []
        }
      }
    },
    "/token-icons/{chain_id}/{token}/{hash}": {
      "get": {
        "operationId": "getTokenIcon",
        "summary": "Fetch a content-addressed token icon",
        "description": "The hash is part of the URL so clients can cache the icon immutably. A hash mismatch returns 404.\n\nAuthentication: None.\n\nScope: Not applicable.",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Icon bytes. The server may return another image MIME type for a custom icon; JSON errors use the standard error envelope.",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "x-json-error-example": {
              "error": {
                "code": "not_found",
                "message": "not_found"
              }
            }
          },
          "404": {
            "description": "not_found: The requested resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "not_found",
                    "message": "not_found"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "chain_id",
            "required": true,
            "description": "EVM chain ID.",
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "example": 12345
          },
          {
            "in": "path",
            "name": "token",
            "required": true,
            "description": "Token contract address.",
            "schema": {
              "type": "string"
            },
            "example": "0x6666666666666666666666666666666666666666"
          },
          {
            "in": "path",
            "name": "hash",
            "required": true,
            "description": "Lowercase SHA-256 content hash.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "example": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          }
        ],
        "x-auth": {
          "kind": "public",
          "apiKeyScopes": []
        }
      }
    },
    "/healthz": {
      "get": {
        "operationId": "healthcheck",
        "summary": "Check liveness",
        "description": "This endpoint is outside `/api/v1`; call `https://platform.invoise.me/healthz`.\n\nAuthentication: None.\n\nScope: Not applicable.",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "const": "ok"
                    }
                  },
                  "required": [
                    "status"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "status": "ok"
                }
              }
            }
          }
        },
        "x-auth": {
          "kind": "public",
          "apiKeyScopes": []
        }
      },
      "servers": [
        {
          "url": "https://platform.invoise.me"
        }
      ]
    },
    "/me": {
      "get": {
        "operationId": "getCurrentPrincipal",
        "summary": "Read the current principal",
        "description": "A session response contains user and csrf. An API-key response is the principal object itself and does not include a CSRF token.\n\nAuthentication: Session bearer token or shop API key; endpoint-specific access checks still apply.\n\nScope: Determined by the session role or the API key's exact scope.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/MeSession"
                    },
                    {
                      "$ref": "#/components/schemas/Principal"
                    }
                  ]
                },
                "example": {
                  "user": {
                    "user_id": "55555555-5555-4555-8555-555555555555",
                    "onboarding_required": false,
                    "mfa_required": false,
                    "mfa_at": null
                  },
                  "csrf": "csrf-token-example"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "x-auth": {
          "kind": "session-or-api-key",
          "apiKeyScopes": []
        }
      }
    },
    "/profile": {
      "get": {
        "operationId": "getProfile",
        "summary": "Read the signed-in profile",
        "description": "Requires a session bearer token. Shop API keys are not account authentication factors.\n\nAuthentication: Session bearer token only; shop API keys are rejected.\n\nScope: Account session; shop scopes do not apply.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profile"
                },
                "example": {
                  "display_name": "Ada Agent",
                  "preferences": {
                    "theme": "system",
                    "language": "en"
                  },
                  "avatar_url": "",
                  "created_at": "2026-09-19T10:00:00Z"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "x-auth": {
          "kind": "session-only",
          "apiKeyScopes": [],
          "sessionOnly": true
        }
      },
      "patch": {
        "operationId": "updateProfile",
        "summary": "Update profile preferences",
        "description": "The handler validates theme as dark, light, or system and language as en or ru. This endpoint is a direct account update and does not use Idempotency-Key.\n\nAuthentication: Session bearer token only; shop API keys are rejected.\n\nScope: Account session; shop scopes do not apply.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Profile"
                },
                "example": {
                  "display_name": "Ada Agent",
                  "preferences": {
                    "theme": "dark",
                    "language": "en"
                  },
                  "avatar_url": "",
                  "created_at": "2026-09-19T10:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "invalid_profile: The profile fields are invalid.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_profile",
                    "message": "invalid_profile"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfilePatch"
              },
              "example": {
                "display_name": "Ada Agent",
                "preferences": {
                  "theme": "dark",
                  "language": "en"
                }
              }
            }
          }
        },
        "x-auth": {
          "kind": "session-only",
          "apiKeyScopes": [],
          "sessionOnly": true
        }
      }
    },
    "/profile/security": {
      "get": {
        "operationId": "getProfileSecurity",
        "summary": "Read account security summary",
        "description": "Returns whether TOTP is enabled and compact passkey metadata. Passkey ceremony endpoints belong to the dashboard sign-in documentation.\n\nAuthentication: Session bearer token only; shop API keys are rejected.\n\nScope: Account session; shop scopes do not apply.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfileSecurity"
                },
                "example": {
                  "totp": true,
                  "passkeys": [
                    {
                      "id": "aabbccddeeff0011",
                      "name": "MacBook passkey",
                      "created_at": "2026-09-19T10:05:00Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "x-auth": {
          "kind": "session-only",
          "apiKeyScopes": [],
          "sessionOnly": true
        }
      }
    },
    "/profile/avatar": {
      "post": {
        "operationId": "uploadProfileAvatar",
        "summary": "Upload a profile avatar",
        "description": "Accepts PNG or JPEG input up to 2048×2048 pixels and returns the normalized inline PNG data URL.\n\nAuthentication: Session bearer token only; shop API keys are rejected.\n\nScope: Account session; shop scopes do not apply.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvatarResponse"
                },
                "example": {
                  "avatar_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB"
                }
              }
            }
          },
          "400": {
            "description": "image_too_large: The decoded or normalized image exceeds its size limit.\n\nKnown error: invalid_image: The image must be a valid PNG or JPEG within the dimension limits.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "image_too_large",
                    "message": "image_too_large"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfileAvatarRequest"
              },
              "example": {
                "image_base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB"
              }
            }
          }
        },
        "x-auth": {
          "kind": "session-only",
          "apiKeyScopes": [],
          "sessionOnly": true
        }
      }
    },
    "/identities": {
      "get": {
        "operationId": "listIdentities",
        "summary": "List linked identities",
        "description": "Returns the identity records linked to the current account.\n\nAuthentication: Session bearer token only; shop API keys are rejected.\n\nScope: Account session; shop scopes do not apply.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Identity"
                  }
                },
                "example": [
                  {
                    "id": "66666666-6666-4666-8666-666666666666",
                    "provider": "email",
                    "label": "agent@example.com"
                  }
                ]
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "x-auth": {
          "kind": "session-only",
          "apiKeyScopes": [],
          "sessionOnly": true
        }
      }
    },
    "/identities/{id}": {
      "delete": {
        "operationId": "unlinkIdentity",
        "summary": "Unlink an identity",
        "description": "Removes a linked sign-in identity. The server refuses to remove the last login method.\n\nAuthentication: Session bearer token only; shop API keys are rejected.\n\nScope: Account session; shop scopes do not apply.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                },
                "example": {
                  "ok": true
                }
              }
            }
          },
          "400": {
            "description": "last_login_method: The account's last sign-in method cannot be removed.\n\nKnown error: not_found: The requested resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "last_login_method",
                    "message": "last_login_method"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "Identity UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "66666666-6666-4666-8666-666666666666"
          }
        ],
        "x-auth": {
          "kind": "session-only",
          "apiKeyScopes": [],
          "sessionOnly": true
        }
      }
    },
    "/onboarding": {
      "post": {
        "operationId": "completeOnboarding",
        "summary": "Complete first-account onboarding",
        "description": "Creates the first merchant and owner grant. It does not create a shop. An account that signed in only with a wallet must also send email, the human owner's address: without it the answer is email_required. That email becomes a sign-in method of the same account; the person signs in to the dashboard with a one-time code and lands in the account the agent created. Send a durable Idempotency-Key and reuse it after an ambiguous response.\n\nAuthentication: Session bearer token only; shop API keys are rejected.\n\nScope: Account session; shop scopes do not apply.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "A repeated completed onboarding request is acknowledged idempotently.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompletedResponse"
                },
                "example": {
                  "completed": true
                }
              }
            }
          },
          "201": {
            "description": "First submission creates the merchant and owner grant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompletedResponse"
                },
                "example": {
                  "completed": true
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_name: The name is empty or exceeds its length limit.\n\nKnown error: email_required: An account without an email sign-in must send the owner's email when completing onboarding.\n\nKnown error: invalid_email: The email address is not valid.\n\nKnown error: disposable_email: Disposable email addresses are not accepted. Use a permanent address.\n\nKnown error: identity_already_linked: This email already belongs to another account.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OnboardingRequest"
              },
              "example": {
                "name": "Agent commerce",
                "email": "owner@example.com"
              }
            }
          }
        },
        "x-auth": {
          "kind": "session-only",
          "apiKeyScopes": [],
          "sessionOnly": true
        }
      }
    },
    "/merchants": {
      "get": {
        "operationId": "listMerchants",
        "summary": "List merchants visible to the caller",
        "description": "Returns merchant IDs and active shop counts. project_limit and project_count are compatibility aliases. A shop API key is restricted to its own merchant.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Merchant"
                  }
                },
                "example": [
                  {
                    "id": "77777777-7777-4777-8777-777777777777",
                    "name": "Agent commerce",
                    "role": "owner",
                    "shop_limit": 10,
                    "shop_count": 1,
                    "project_limit": 10,
                    "project_count": 1
                  }
                ]
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      },
      "post": {
        "operationId": "createMerchant",
        "summary": "Create merchant (always forbidden)",
        "description": "The public route remains for compatibility but always returns forbidden. The first merchant is created by POST /onboarding; additional merchants are assigned administratively.\n\nAuthentication: Session bearer token or shop API key; endpoint-specific access checks still apply.\n\nScope: Determined by the session role or the API key's exact scope.",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "This route is always forbidden; use POST /onboarding for the first merchant.\n\nKnown error: forbidden: The authenticated principal cannot perform this operation.\n\nKnown error: mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "forbidden",
                    "message": "forbidden"
                  }
                }
              }
            }
          }
        },
        "x-auth": {
          "kind": "session-or-api-key",
          "apiKeyScopes": []
        }
      }
    },
    "/merchants/{merchant_id}/networks": {
      "get": {
        "operationId": "listMerchantNetworks",
        "summary": "List networks enabled for a merchant",
        "description": "The result is the public network catalog filtered by merchant policy, with minimum_payment per network and, on Solana, wallet_bridge. A read-scoped API key may read only its own shop's merchant.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Network"
                  }
                },
                "example": [
                  {
                    "chain_id": 12345,
                    "name": "Example network",
                    "main_factory": "0x1111111111111111111111111111111111111111",
                    "invoice_factory": "0x2222222222222222222222222222222222222222",
                    "start_block": 12000000,
                    "tokens": [],
                    "minimum_payment": "1"
                  }
                ]
              }
            }
          },
          "400": {
            "description": "invalid_merchant: The merchant identifier is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_merchant",
                    "message": "invalid_merchant"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          }
        ],
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      }
    },
    "/merchants/{merchant_id}/overview": {
      "get": {
        "operationId": "getMerchantOverview",
        "summary": "Read merchant metrics",
        "description": "The shop overview across every shop of the merchant, with shops_breakdown giving volume and payment count per active shop. Any member can read it; a read-scoped API key only for its own shop's merchant.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Overview"
                },
                "example": {
                  "days": 30,
                  "sandbox": false,
                  "currency": "USDT / USDC",
                  "timezone": "UTC",
                  "merchant_name": "Agent commerce",
                  "shops": 1,
                  "projects": 1,
                  "volume": "125.50",
                  "payout": "124.20",
                  "fees": "1.30",
                  "payments": 8,
                  "late": "0",
                  "excess": "0",
                  "invoices": 5,
                  "deposits": 3,
                  "series": [
                    {
                      "day": "2026-09-19",
                      "volume": "125.50",
                      "payout": "124.20",
                      "fees": "1.30",
                      "payments": 8
                    }
                  ],
                  "statuses": [
                    {
                      "status": "settled",
                      "count": 4
                    },
                    {
                      "status": "open",
                      "count": 2
                    }
                  ],
                  "shops_breakdown": [
                    {
                      "id": "11111111-1111-4111-8111-111111111111",
                      "name": "Agent payments",
                      "volume": "125.50",
                      "payments": 8
                    }
                  ],
                  "networks": [
                    {
                      "chain_id": 12345,
                      "volume": "125.50",
                      "payments": 8
                    }
                  ],
                  "webhooks": {
                    "delivered": 7,
                    "failed": 0,
                    "pending": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "invalid_merchant: The merchant identifier is invalid.\n\nKnown error: invalid_period: The requested period is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_merchant",
                    "message": "invalid_merchant"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          },
          {
            "in": "query",
            "name": "days",
            "required": false,
            "description": "Aggregation window.",
            "schema": {
              "type": "integer",
              "enum": [
                7,
                30,
                90
              ]
            },
            "example": 30
          },
          {
            "in": "query",
            "name": "sandbox",
            "required": false,
            "description": "true reads the sandbox shops instead of live ones.",
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            },
            "example": "false"
          }
        ],
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      }
    },
    "/merchants/{merchant_id}/tariffs": {
      "get": {
        "operationId": "getMerchantTariffs",
        "summary": "Read merchant fees",
        "description": "The merchant's current fees per enabled network, in the shape of GET /shops/{shop_id}/terms without a shop's sweep settings.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MerchantTerms"
                  }
                },
                "example": [
                  {
                    "chain_id": 12345,
                    "family": "evm",
                    "name": "Example network",
                    "enabled": true,
                    "invoice": {
                      "bps": 50,
                      "minimum": "30000000000000000",
                      "maximum": "100000000000000000000"
                    },
                    "deposit": {
                      "bps": 50,
                      "minimum": "30000000000000000",
                      "maximum": "100000000000000000000"
                    }
                  }
                ]
              }
            }
          },
          "400": {
            "description": "invalid_merchant: The merchant identifier is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_merchant",
                    "message": "invalid_merchant"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          }
        ],
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      }
    },
    "/merchants/{merchant_id}/payout-wallets": {
      "get": {
        "operationId": "listPayoutWallets",
        "summary": "List Invoise wallets a shop can pay into",
        "description": "The caller's own wallet comes first, even before it is set up; other members with access to the whole merchant are listed only once their wallet is ready. Use user_id as payout_wallet_user_id when creating or updating a shop.\n\nAuthentication: Session bearer token only; shop API keys are rejected.\n\nScope: Account session; shop scopes do not apply.",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PayoutWalletOption"
                  }
                },
                "example": [
                  {
                    "user_id": "55555555-5555-4555-8555-555555555555",
                    "display_name": "Ada Agent",
                    "ready": true,
                    "avatar_url": "",
                    "self": true
                  }
                ]
              }
            }
          },
          "400": {
            "description": "invalid_merchant: The merchant identifier is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_merchant",
                    "message": "invalid_merchant"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          }
        ],
        "x-auth": {
          "kind": "session-only",
          "apiKeyScopes": [],
          "sessionOnly": true
        }
      }
    },
    "/merchants/{merchant_id}/shops": {
      "get": {
        "operationId": "listShops",
        "summary": "List shops for a merchant",
        "description": "The canonical route uses shops. The former /projects route is a direct alias with the same permissions and idempotency scopes.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Shop"
                  }
                },
                "example": [
                  {
                    "id": "11111111-1111-4111-8111-111111111111",
                    "shop_id": "11111111-1111-4111-8111-111111111111",
                    "name": "Agent payments",
                    "sandbox": false,
                    "recipient": "0x4444444444444444444444444444444444444444",
                    "delegate": "0x0000000000000000000000000000000000000000",
                    "archived": false,
                    "settings_version": 3,
                    "payout_target": "address",
                    "solana_recipient": "",
                    "solana_enabled": false,
                    "solana_payout_target": "address",
                    "tron_recipient": "",
                    "tron_enabled": false,
                    "tron_payout_target": "address",
                    "tron_bridge_ready": false
                  }
                ]
              }
            }
          },
          "400": {
            "description": "invalid_merchant: The merchant identifier is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_merchant",
                    "message": "invalid_merchant"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          }
        ],
        "x-legacy-path": "/merchants/{merchant}/projects",
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      },
      "post": {
        "operationId": "createShop",
        "summary": "Create a shop",
        "description": "Pay EVM payouts to recipient (payout_target address, the default) or into an Invoise wallet (payout_target wallet; a wallet shop also takes Solana into that wallet). The recipient and delegate can be changed later with PATCH /shops/{shop_id}; every invoice and deposit keeps the ones it was created with. Set sandbox to true for simulations; each merchant can have at most one sandbox shop, and it cannot pay into a wallet.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShopCreateResponse"
                },
                "example": {
                  "id": "11111111-1111-4111-8111-111111111111",
                  "shop_id": "11111111-1111-4111-8111-111111111111",
                  "name": "Agent payments",
                  "sandbox": false,
                  "recipient": "0x4444444444444444444444444444444444444444",
                  "delegate": "0x0000000000000000000000000000000000000000",
                  "branding": {
                    "name": "Agent payments"
                  },
                  "payout_target": "address"
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_name: The name is empty or exceeds its length limit.\n\nKnown error: invalid_payout_target: A payout target must be address or wallet.\n\nKnown error: invalid_payout_wallet: payout_wallet_user_id is not a member with access to the whole merchant.\n\nKnown error: wallet_not_ready: The selected Invoise wallet is not set up yet.\n\nKnown error: sandbox_wallet_unavailable: A sandbox shop cannot pay into an Invoise wallet.\n\nKnown error: recipient_required: A non-zero recipient address is required.\n\nKnown error: invalid_address: The address is not a valid EVM address.\n\nKnown error: invalid_recipient: The recipient must not be the zero address.\n\nKnown error: sandbox_already_exists: A merchant can have only one sandbox shop.\n\nKnown error: shop_limit_reached: The merchant has reached its active shop limit.\n\nKnown error: merchant_disabled: The merchant is disabled.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateShopRequest"
              },
              "example": {
                "name": "Agent payments",
                "sandbox": false,
                "recipient": "0x4444444444444444444444444444444444444444",
                "delegate": "0x0000000000000000000000000000000000000000"
              }
            }
          }
        },
        "x-legacy-path": "/merchants/{merchant}/projects",
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/merchants/{merchant_id}/team": {
      "get": {
        "operationId": "getMerchantTeam",
        "summary": "Read team grants and invites",
        "description": "Merchant administration is owner-only. Each grant and invite exposes both canonical shop_id and legacy project_id where applicable.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Team"
                },
                "example": {
                  "grants": [
                    {
                      "id": "88888888-8888-4888-8888-888888888888",
                      "user_id": "55555555-5555-4555-8555-555555555555",
                      "shop_id": null,
                      "project_id": null,
                      "role": "owner",
                      "display_name": "Ada Agent",
                      "identity": "agent@example.com",
                      "email": "agent@example.com",
                      "avatar_url": ""
                    }
                  ],
                  "invites": [
                    {
                      "id": "99999999-9999-4999-8999-999999999999",
                      "subject": "developer@example.com",
                      "provider": "email",
                      "shop_id": "11111111-1111-4111-8111-111111111111",
                      "project_id": "11111111-1111-4111-8111-111111111111",
                      "role": "developer",
                      "expires_at": "2026-09-26T10:00:00Z",
                      "accepted_by": null,
                      "revoked_at": null,
                      "status": "pending",
                      "email_sent": true,
                      "email_status": "sent",
                      "email_sent_at": "2026-09-19T10:00:01Z",
                      "email_error": null
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          }
        ],
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/merchants/{merchant_id}/team/{user_id}/avatar": {
      "get": {
        "operationId": "getTeamAvatar",
        "summary": "Fetch a team member avatar",
        "description": "The caller must be a merchant owner and the user must have a grant in that merchant.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "PNG bytes. JSON errors use the standard error envelope.",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "x-json-error-example": {
              "error": {
                "code": "not_found",
                "message": "not_found"
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found: The requested resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "not_found",
                    "message": "not_found"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          },
          {
            "in": "path",
            "name": "user_id",
            "required": true,
            "description": "Team member user UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "55555555-5555-4555-8555-555555555555"
          }
        ],
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/merchants/{merchant_id}/invites": {
      "post": {
        "operationId": "createInvite",
        "summary": "Invite a team member",
        "description": "Use provider, subject, role, and optionally shop_id. The correct email field is subject; an email field is not part of the request. The response includes persisted invite and email delivery state.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteDelivery"
                },
                "example": {
                  "id": "99999999-9999-4999-8999-999999999999",
                  "invite_url": "https://invoise.me/?invite=99999999-9999-4999-8999-999999999999",
                  "status": "pending",
                  "revoked_at": null,
                  "email_sent": true,
                  "email_status": "sent",
                  "email_sent_at": "2026-09-19T10:00:01Z",
                  "email_error": null
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_provider: provider must be email or wallet.\n\nKnown error: invalid_email: The email address is not valid.\n\nKnown error: invalid_wallet: subject is not a valid wallet address.\n\nKnown error: invalid_role: role must be owner, developer, or viewer.\n\nKnown error: invalid_shop: The shop identifier is invalid.\n\nKnown error: invalid_project: The legacy project identifier is invalid.\n\nKnown error: conflicting_shop_id: shop_id and project_id disagree.\n\nKnown error: shop_not_found: The selected shop does not exist for this merchant.\n\nKnown error: shop_archived: The shop is archived.\n\nKnown error: team_limit_reached: Members plus pending invitations have reached the merchant's team limit.\n\nKnown error: email_unavailable: The invite was created, but email delivery is unavailable.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteRequest"
              },
              "example": {
                "provider": "email",
                "subject": "developer@example.com",
                "role": "developer",
                "shop_id": "11111111-1111-4111-8111-111111111111"
              }
            }
          }
        },
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/merchants/{merchant_id}/invites/{id}": {
      "delete": {
        "operationId": "revokeInvite",
        "summary": "Revoke an invite",
        "description": "Revocation is idempotent for the same invite and cannot undo an accepted invite.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteRevokeResponse"
                },
                "example": {
                  "id": "99999999-9999-4999-8999-999999999999",
                  "status": "revoked",
                  "revoked": true,
                  "revoked_at": "2026-09-19T10:15:00Z"
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_invite: The invite identifier is invalid.\n\nKnown error: invite_not_found: The invite does not exist for this merchant.\n\nKnown error: invite_already_accepted: The invite has already been accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "Invite UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "99999999-9999-4999-8999-999999999999"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/invites/{id}/accept": {
      "post": {
        "operationId": "acceptInvite",
        "summary": "Accept an invite",
        "description": "The signed-in session must prove the identity named by the invite. API keys cannot accept invites.\n\nAuthentication: Session bearer token only; shop API keys are rejected.\n\nScope: Account session; shop scopes do not apply.",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InviteAcceptResponse"
                },
                "example": {
                  "merchant_id": "77777777-7777-4777-8777-777777777777"
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_invite: The invite identifier is invalid.\n\nKnown error: invite_unavailable: The invite is expired or unavailable.\n\nKnown error: invite_revoked: The invite has been revoked.\n\nKnown error: invite_already_accepted: The invite has already been accepted.\n\nKnown error: invite_identity_required: The accepting session must prove the invited identity.\n\nKnown error: invite_role_conflict: The existing grant is stronger than this invite.\n\nKnown error: team_limit_reached: Members plus pending invitations have reached the merchant's team limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "Invite UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "99999999-9999-4999-8999-999999999999"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "x-auth": {
          "kind": "session-only",
          "apiKeyScopes": [],
          "sessionOnly": true
        }
      }
    },
    "/merchants/{merchant_id}/grants/{id}": {
      "delete": {
        "operationId": "revokeGrant",
        "summary": "Revoke a team grant",
        "description": "Only a merchant owner can revoke grants. The last merchant-wide owner cannot be removed.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Merchants and team"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GrantRevokeResponse"
                },
                "example": {
                  "revoked": true
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: last_merchant_owner: The last merchant owner cannot be removed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "merchant_id",
            "required": true,
            "description": "Merchant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "77777777-7777-4777-8777-777777777777"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "Grant UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "88888888-8888-4888-8888-888888888888"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/shops/{shop_id}": {
      "patch": {
        "operationId": "updateShop",
        "summary": "Update shop settings",
        "description": "Change the name, archive state, sweep thresholds, EVM recipient and delegate, and where each network family pays: an own address or an Invoise wallet. Every invoice and deposit keeps the recipient and delegate it was created with, so a change reaches only new invoices and addresses. Changing where the shop pays needs owner rights over the whole merchant. A shop paying into a wallet has no recipient of its own; send payout_target address with a recipient to move it back.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdatedResponse"
                },
                "example": {
                  "updated": true
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_shop: The shop identifier is invalid.\n\nKnown error: invalid_name: The name is empty or exceeds its length limit.\n\nKnown error: invalid_recipient: The recipient must not be the zero address.\n\nKnown error: invalid_address: The address is not a valid EVM address.\n\nKnown error: invalid_payout_target: A payout target must be address or wallet.\n\nKnown error: invalid_payout_wallet: payout_wallet_user_id is not a member with access to the whole merchant.\n\nKnown error: wallet_not_ready: The selected Invoise wallet is not set up yet.\n\nKnown error: sandbox_wallet_unavailable: A sandbox shop cannot pay into an Invoise wallet.\n\nKnown error: tron_bridge_unavailable: Tron payments cannot reach the Invoise wallet; keep Tron on its own address.\n\nKnown error: invalid_sweep_threshold: A sweep threshold is unknown or outside the allowed range.\n\nKnown error: shop_limit_reached: The merchant has reached its active shop limit.\n\nKnown error: sandbox_already_exists: A merchant can have only one sandbox shop.\n\nKnown error: shop_archived: The shop is archived.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShopPatchRequest"
              },
              "example": {
                "name": "Agent payments v2",
                "recipient": "0x4444444444444444444444444444444444444444",
                "sweep_thresholds": {
                  "12345": "10"
                }
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}",
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/shops/{shop_id}/overview": {
      "get": {
        "operationId": "getShopOverview",
        "summary": "Read shop metrics",
        "description": "The default window is 30 days. Supported windows are 7, 30, and 90 days; amounts are display-unit strings.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Overview"
                },
                "example": {
                  "days": 30,
                  "sandbox": false,
                  "currency": "TOKEN",
                  "timezone": "UTC",
                  "merchant_name": "Agent commerce",
                  "shops": 1,
                  "projects": 1,
                  "volume": "125.50",
                  "payout": "124.20",
                  "fees": "1.30",
                  "payments": 8,
                  "late": "0",
                  "excess": "0",
                  "invoices": 5,
                  "deposits": 3,
                  "series": [
                    {
                      "day": "2026-09-19",
                      "volume": "125.50",
                      "payout": "124.20",
                      "fees": "1.30",
                      "payments": 8
                    }
                  ],
                  "statuses": [
                    {
                      "status": "settled",
                      "count": 4
                    },
                    {
                      "status": "open",
                      "count": 2
                    }
                  ],
                  "shops_breakdown": [],
                  "networks": [
                    {
                      "chain_id": 12345,
                      "volume": "125.50",
                      "payments": 8
                    }
                  ],
                  "webhooks": {
                    "delivered": 7,
                    "failed": 0,
                    "pending": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "invalid_period: The requested period is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_period",
                    "message": "invalid_period"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "query",
            "name": "days",
            "required": false,
            "description": "Aggregation window.",
            "schema": {
              "type": "integer",
              "enum": [
                7,
                30,
                90
              ]
            },
            "example": 30
          }
        ],
        "x-legacy-path": "/projects/{project}/overview",
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      }
    },
    "/shops/{shop_id}/terms": {
      "get": {
        "operationId": "getShopTerms",
        "summary": "Read shop tariffs and sweep terms",
        "description": "Returns per-network invoice/deposit tariffs, minimums, maximums, and the active sweep threshold. Tariff minimum/maximum are unsigned integer strings in 18-decimal units independent of token decimals; sweep thresholds and sweep limits are human-readable token-unit strings.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ShopTerms"
                  }
                },
                "example": [
                  {
                    "chain_id": 12345,
                    "family": "evm",
                    "name": "Example network",
                    "enabled": true,
                    "minimum_sweep": "1",
                    "maximum_sweep": "10000",
                    "sweep_threshold": "10",
                    "invoice": {
                      "bps": 50,
                      "minimum": "30000000000000000",
                      "maximum": "100000000000000000000"
                    },
                    "deposit": {
                      "bps": 50,
                      "minimum": "30000000000000000",
                      "maximum": "100000000000000000000"
                    }
                  }
                ]
              }
            }
          },
          "400": {
            "description": "invalid_shop: The shop identifier is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_shop",
                    "message": "invalid_shop"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          }
        ],
        "x-legacy-path": "/projects/{project}/terms",
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      }
    },
    "/shops/{shop_id}/branding": {
      "get": {
        "operationId": "getShopBranding",
        "summary": "Read checkout branding",
        "description": "Returns the shop branding object used by public checkout. The logo URL must point to an asset owned by this shop.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Branding"
                },
                "example": {
                  "name": "Agent payments",
                  "logo": "/api/v1/assets/44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "400": {
            "description": "invalid_shop: The shop identifier is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_shop",
                    "message": "invalid_shop"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          }
        ],
        "x-legacy-path": "/projects/{project}/branding",
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      },
      "put": {
        "operationId": "replaceShopBranding",
        "summary": "Update checkout branding with PUT",
        "description": "PUT and PATCH use the same partial merge handler. Supplying image_base64 stores a normalized PNG asset and updates logo.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Branding"
                },
                "example": {
                  "name": "Agent payments",
                  "logo": "/api/v1/assets/44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_name: The name is empty or exceeds its length limit.\n\nKnown error: image_too_large: The decoded or normalized image exceeds its size limit.\n\nKnown error: invalid_image: The image must be a valid PNG or JPEG within the dimension limits.\n\nKnown error: invalid_logo: The logo must reference an asset owned by this shop.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BrandingPatchRequest"
              },
              "example": {
                "name": "Agent payments",
                "image_base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB"
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/branding",
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      },
      "patch": {
        "operationId": "patchShopBranding",
        "summary": "Update checkout branding with PATCH",
        "description": "PATCH is the same partial merge operation as PUT; omitted properties remain unchanged.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Branding"
                },
                "example": {
                  "name": "Agent payments",
                  "logo": "/api/v1/assets/44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_name: The name is empty or exceeds its length limit.\n\nKnown error: image_too_large: The decoded or normalized image exceeds its size limit.\n\nKnown error: invalid_image: The image must be a valid PNG or JPEG within the dimension limits.\n\nKnown error: invalid_logo: The logo must reference an asset owned by this shop.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BrandingPatchRequest"
              },
              "example": {
                "logo": "/api/v1/assets/44444444-4444-4444-8444-444444444444"
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/branding",
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/shops/{shop_id}/export.csv": {
      "get": {
        "operationId": "exportShopPayments",
        "summary": "Export shop payments as CSV",
        "description": "The default period is the last month. The maximum period is 366 days and the result is capped at 50000 rows.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "CSV with up to 50000 rows and columns id, kind, chain_id, token, amount_raw, status, description, external_id, created_at. JSON errors use the standard error envelope.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "x-json-error-example": {
              "error": {
                "code": "invalid_period",
                "message": "invalid_period"
              }
            }
          },
          "400": {
            "description": "invalid_period: The requested period is invalid.\n\nKnown error: invalid_kind: kind must be invoice or deposit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_period",
                    "message": "invalid_period"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "query",
            "name": "from",
            "required": false,
            "description": "RFC 3339 start timestamp; defaults to one month ago.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-09-01T00:00:00Z"
          },
          {
            "in": "query",
            "name": "to",
            "required": false,
            "description": "RFC 3339 end timestamp; defaults to now.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-09-19T23:59:59Z"
          },
          {
            "in": "query",
            "name": "chain_id",
            "required": false,
            "description": "Optional chain ID filter.",
            "schema": {
              "type": "string"
            },
            "example": "12345"
          },
          {
            "in": "query",
            "name": "token",
            "required": false,
            "description": "Optional token address filter.",
            "schema": {
              "type": "string"
            },
            "example": "0x6666666666666666666666666666666666666666"
          },
          {
            "in": "query",
            "name": "kind",
            "required": false,
            "description": "Optional issuance kind filter.",
            "schema": {
              "type": "string",
              "enum": [
                "invoice",
                "deposit"
              ]
            },
            "example": "invoice"
          }
        ],
        "x-legacy-path": "/projects/{project}/export.csv",
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      }
    },
    "/shops/{shop_id}/solana-recipient": {
      "get": {
        "operationId": "getSolanaRecipient",
        "summary": "Read the shop's Solana recipient",
        "description": "Returns the wallet that receives Solana payouts, or an empty address until one is set. The shop cannot issue on Solana to an address before it is set (solana_setup_required).\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FamilyRecipient"
                },
                "example": {
                  "address": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          }
        ],
        "x-legacy-path": "/projects/{project}/solana-recipient",
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      },
      "put": {
        "operationId": "setSolanaRecipient",
        "summary": "Set the shop's Solana recipient",
        "description": "Sets the wallet that receives Solana payouts. It is set once: repeating the same address succeeds, another address returns shop_addresses_immutable (project_addresses_immutable on /projects routes). Before issuing a token, the wallet must already hold an account for it.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FamilyRecipient"
                },
                "example": {
                  "address": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV"
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_solana_address: The address is not an ordinary Solana wallet, or it belongs to Invoise.\n\nKnown error: shop_addresses_immutable: The shop's Solana or Tron recipient is already set to another address and cannot be changed.\n\nKnown error: shop_archived: The shop is archived.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FamilyRecipientRequest"
              },
              "example": {
                "address": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV"
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/solana-recipient",
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/shops/{shop_id}/tron-recipient": {
      "get": {
        "operationId": "getTronRecipient",
        "summary": "Read the shop's Tron recipient",
        "description": "Returns the wallet that receives Tron payouts, or an empty address until one is set. The shop cannot issue on Tron to an address before it is set (tron_setup_required).\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FamilyRecipient"
                },
                "example": {
                  "address": "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          }
        ],
        "x-legacy-path": "/projects/{project}/tron-recipient",
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      },
      "put": {
        "operationId": "setTronRecipient",
        "summary": "Set the shop's Tron recipient",
        "description": "Sets the wallet that receives Tron payouts. It is set once: repeating the same address succeeds, another address returns shop_addresses_immutable (project_addresses_immutable on /projects routes). The merchant needs a Tron network switched on (merchant_network_disabled otherwise).\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Shops"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FamilyRecipient"
                },
                "example": {
                  "address": "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_tron_address: The address is not a valid Tron wallet address.\n\nKnown error: invalid_tron_checksum: The Tron address checksum does not match.\n\nKnown error: invalid_tron_recipient: The Tron recipient belongs to Invoise and cannot receive payouts.\n\nKnown error: merchant_network_disabled: The selected network is disabled for this merchant.\n\nKnown error: shop_addresses_immutable: The shop's Solana or Tron recipient is already set to another address and cannot be changed.\n\nKnown error: shop_archived: The shop is archived.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FamilyRecipientRequest"
              },
              "example": {
                "address": "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf"
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/tron-recipient",
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/shops/{shop_id}/payments": {
      "get": {
        "operationId": "listPayments",
        "summary": "List invoices and deposits",
        "description": "The default response is an array. Add limit or cursor to use cursor pagination. received is not returned here; use the detail endpoint for cumulative confirmed receipts. A group is one row with group: true and its options in assets.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Invoices and deposits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Without limit or cursor the response is a JSON array. Supplying either switches to {items,next_cursor}; limit is validated as 1–100.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PaymentSummary"
                      }
                    },
                    {
                      "$ref": "#/components/schemas/PaymentListPage"
                    }
                  ]
                },
                "examples": {
                  "example1": {
                    "value": [
                      {
                        "id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
                        "shop_id": "11111111-1111-4111-8111-111111111111",
                        "public_id": "pay_7Jm2Qp8K4dR6sT9v",
                        "kind": "invoice",
                        "chain_id": 12345,
                        "token": "0x6666666666666666666666666666666666666666",
                        "amount": "10000000",
                        "address": "0x3333333333333333333333333333333333333333",
                        "status": "funded",
                        "description": "Order 1042",
                        "external_id": "order-1042",
                        "created_at": "2026-09-19T09:00:00Z",
                        "cancelled_at": null,
                        "disabled_at": null,
                        "expires_at": "2026-10-19T09:00:00Z",
                        "payment_url": "https://pay.invoise.me/pay_7Jm2Qp8K4dR6sT9v"
                      }
                    ]
                  },
                  "example2": {
                    "value": {
                      "items": [
                        {
                          "id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
                          "shop_id": "11111111-1111-4111-8111-111111111111",
                          "public_id": "pay_7Jm2Qp8K4dR6sT9v",
                          "kind": "invoice",
                          "chain_id": 12345,
                          "token": "0x6666666666666666666666666666666666666666",
                          "amount": "10000000",
                          "address": "0x3333333333333333333333333333333333333333",
                          "status": "funded",
                          "description": "Order 1042",
                          "external_id": "order-1042",
                          "created_at": "2026-09-19T09:00:00Z",
                          "cancelled_at": null,
                          "disabled_at": null,
                          "expires_at": "2026-10-19T09:00:00Z",
                          "payment_url": "https://pay.invoise.me/pay_7Jm2Qp8K4dR6sT9v"
                        }
                      ],
                      "next_cursor": "eyJhdCI6IjIwMjYtMDktMTlUMDk6MDA6MDBaIiwiaWQiOiJhYWFhYWFhYS1hYWFhLTRhYWEtOGFhYS1hYWFhYWFhYWFhYWFhYWFhYWFhIn0"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "invalid_kind: kind must be invoice or deposit.\n\nKnown error: invalid_query: The search query is too long.\n\nKnown error: invalid_limit: limit must be between 1 and 100.\n\nKnown error: invalid_cursor: The cursor is malformed or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_kind",
                    "message": "invalid_kind"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "query",
            "name": "kind",
            "required": false,
            "description": "Filter by issuance kind.",
            "schema": {
              "type": "string",
              "enum": [
                "invoice",
                "deposit"
              ]
            },
            "example": "invoice"
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "description": "Filter by status or derived filter active, disabled, cancelled, or paid.",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "disabled",
                "cancelled",
                "paid",
                "registering",
                "open",
                "funded",
                "settled",
                "reconciling"
              ]
            },
            "example": "funded"
          },
          {
            "in": "query",
            "name": "q",
            "required": false,
            "description": "Case-insensitive search over description, IDs, and address.",
            "schema": {
              "type": "string"
            },
            "example": "order-1042"
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "When present, switches the response to cursor pagination; 1–100.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "example": 25
          },
          {
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Opaque cursor returned as next_cursor.",
            "schema": {
              "type": "string"
            },
            "example": "cursor-demo-1"
          }
        ],
        "x-legacy-path": "/projects/{project}/payments",
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      }
    },
    "/shops/{shop_id}/invoices": {
      "post": {
        "operationId": "createInvoice",
        "summary": "Create a fixed invoice",
        "description": "Returns 202 with id, shop_id, public_id, status, nullable address, payment_url and expires_at. Poll the issuance endpoint until the address is exposed; never derive an address from an incomplete response. Send assets instead of chain_id and token to let the payer choose among several tokens or networks; the response then has group: true and options, one per asset, and the whole group is paid once. A failed option is named in error.details.\n\nAuthentication: Session or an `ivk_` key with the exact `write` scope. `write` does not imply `read`.\n\nScope: `write`",
        "tags": [
          "Invoices and deposits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "The route returns 202 and may leave address null while watch registration is pending. With assets the response is a group: one option per asset, each with its own address.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/CreateIssuanceResponse"
                    },
                    {
                      "$ref": "#/components/schemas/CreateIssuanceGroupResponse"
                    }
                  ]
                },
                "examples": {
                  "example1": {
                    "value": {
                      "id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
                      "shop_id": "11111111-1111-4111-8111-111111111111",
                      "public_id": "pay_4Kp8Vn2Lm6Qr9XsT",
                      "status": "registering",
                      "address": null,
                      "payment_url": "https://pay.invoise.me/pay_4Kp8Vn2Lm6Qr9XsT",
                      "expires_at": "2026-10-19T09:00:00Z"
                    }
                  },
                  "example2": {
                    "value": {
                      "id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
                      "group": true,
                      "shop_id": "11111111-1111-4111-8111-111111111111",
                      "public_id": "pay_9Tq3Wm5Rz8Kd2YpL",
                      "status": "registering",
                      "payment_url": "https://pay.invoise.me/pay_9Tq3Wm5Rz8Kd2YpL",
                      "options": [
                        {
                          "id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
                          "public_id": "pay_4Kp8Vn2Lm6Qr9XsT",
                          "chain_id": 12345,
                          "token": "0x6666666666666666666666666666666666666666",
                          "token_decimals": 6,
                          "family": "evm",
                          "amount": "10500000",
                          "address": null,
                          "status": "registering"
                        },
                        {
                          "id": "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
                          "public_id": "pay_2Hs6Xb9Nc4Vf7GjR",
                          "chain_id": 67890,
                          "token": "0x7777777777777777777777777777777777777777",
                          "token_decimals": 18,
                          "family": "evm",
                          "amount": "10500000000000000000",
                          "address": null,
                          "status": "registering"
                        }
                      ],
                      "expires_at": "2026-10-19T09:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_description: description or external_id exceeds its length limit.\n\nKnown error: invalid_return_url: return_url must be an HTTPS URL without userinfo.\n\nKnown error: invalid_assets: assets must be a non-empty list of distinct {chain_id, token} pairs, sent without chain_id and token.\n\nKnown error: merchant_disabled: The merchant is disabled.\n\nKnown error: merchant_network_disabled: The selected network is disabled for this merchant.\n\nKnown error: network_disabled: The network is switched off or not running right now.\n\nKnown error: unsupported_network: The chain ID is not a network Invoise supports.\n\nKnown error: unsupported_asset: The network or token is not available for this shop.\n\nKnown error: shop_archived: The shop is archived.\n\nKnown error: asset_not_ready: The selected production asset is not ready.\n\nKnown error: network_not_ready: The selected network factory is not ready.\n\nKnown error: recipient_required: A non-zero recipient address is required.\n\nKnown error: wallet_not_ready: The selected Invoise wallet is not set up yet.\n\nKnown error: solana_setup_required: Set the shop's Solana recipient before issuing on Solana.\n\nKnown error: solana_recipient_token_account_required: The Solana recipient has no account for this token yet; receive the token there once first.\n\nKnown error: solana_bridge_unavailable: Solana payments cannot be bridged into the Invoise wallet right now.\n\nKnown error: solana_sandbox_unavailable: Solana is not available in a sandbox shop.\n\nKnown error: tron_setup_required: Set the shop's Tron recipient before issuing on Tron.\n\nKnown error: invalid_tron_recipient: The Tron recipient belongs to Invoise and cannot receive payouts.\n\nKnown error: tron_bridge_unavailable: Tron payments cannot reach the Invoise wallet; keep Tron on its own address.\n\nKnown error: invalid_amount: The amount of a multi-option invoice is not a decimal token amount valid for every option.\n\nKnown error: amount_below_minimum: The invoice amount is below the network's minimum_payment.\n\nKnown error: invalid_expires_in: expires_in must be 1d, 7d, 30d, 180d or 365d, and only invoices accept it.\n\nKnown error: fee_exceeds_amount: The configured fee would consume the invoice amount.\n\nKnown error: invoice_amount_limit: One invoice can be at most 1,000,000 tokens.\n\nKnown error: sandbox_amount_limit: A sandbox invoice or simulated transfer can be at most 10,000 tokens.\n\nKnown error: active_invoice_limit_reached: The merchant has reached its limit of active invoices.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "amount is required for invoices and is an integer string in the token's smallest units.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvoiceRequest"
              },
              "example": {
                "chain_id": 12345,
                "token": "0x6666666666666666666666666666666666666666",
                "amount": "10000000",
                "expires_in": "7d",
                "description": "Order 1042",
                "external_id": "order-1042",
                "return_url": "https://merchant.example/paid"
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/invoices",
        "x-auth": {
          "kind": "session-or-write-key",
          "apiKeyScopes": [
            "write"
          ]
        }
      }
    },
    "/shops/{shop_id}/invoices/{id}/cancel": {
      "post": {
        "operationId": "cancelInvoice",
        "summary": "Cancel an unpaid invoice checkout",
        "description": "Cancellation hides the checkout off-chain. It does not change settlement state or erase incoming accounting; funded and settled invoices cannot be cancelled. For a group, send the group id: every option is cancelled together. An option's own id returns issuance_in_group.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Invoices and deposits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelResponse"
                },
                "example": {
                  "cancelled": true
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invoice_not_found: The invoice does not exist in this shop.\n\nKnown error: not_an_invoice: The issuance is not an invoice.\n\nKnown error: invoice_already_paid: A funded or settled invoice cannot be cancelled.\n\nKnown error: issuance_in_group: This invoice or deposit is one option of a group; cancel or switch the group by its id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "Invoice issuance UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "x-legacy-path": "/projects/{project}/invoices/{id}/cancel",
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/shops/{shop_id}/deposits": {
      "post": {
        "operationId": "createDeposit",
        "summary": "Create a free-amount deposit address",
        "description": "Send chain_id and token, or assets for one address per token and network; omit amount or send \"0\". The returned address may be null while registration is pending. Deposits do not expire; expires_in is rejected.\n\nAuthentication: Session or an `ivk_` key with the exact `write` scope. `write` does not imply `read`.\n\nScope: `write`",
        "tags": [
          "Invoices and deposits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "The response shape is the same issuance reference; address is null until registration for a real shop. With assets the response is a group with one address per asset; expires_at is null.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/CreateIssuanceResponse"
                    },
                    {
                      "$ref": "#/components/schemas/CreateIssuanceGroupResponse"
                    }
                  ]
                },
                "examples": {
                  "example1": {
                    "value": {
                      "id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
                      "shop_id": "11111111-1111-4111-8111-111111111111",
                      "public_id": "pay_4Kp8Vn2Lm6Qr9XsT",
                      "status": "registering",
                      "address": null,
                      "payment_url": "https://pay.invoise.me/pay_4Kp8Vn2Lm6Qr9XsT",
                      "expires_at": "2026-10-19T09:00:00Z"
                    }
                  },
                  "example2": {
                    "value": {
                      "id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
                      "group": true,
                      "shop_id": "11111111-1111-4111-8111-111111111111",
                      "public_id": "pay_9Tq3Wm5Rz8Kd2YpL",
                      "status": "registering",
                      "payment_url": "https://pay.invoise.me/pay_9Tq3Wm5Rz8Kd2YpL",
                      "options": [
                        {
                          "id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
                          "public_id": "pay_4Kp8Vn2Lm6Qr9XsT",
                          "chain_id": 12345,
                          "token": "0x6666666666666666666666666666666666666666",
                          "token_decimals": 6,
                          "family": "evm",
                          "amount": "10500000",
                          "address": null,
                          "status": "registering"
                        },
                        {
                          "id": "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
                          "public_id": "pay_2Hs6Xb9Nc4Vf7GjR",
                          "chain_id": 67890,
                          "token": "0x7777777777777777777777777777777777777777",
                          "token_decimals": 18,
                          "family": "evm",
                          "amount": "10500000000000000000",
                          "address": null,
                          "status": "registering"
                        }
                      ],
                      "expires_at": "2026-10-19T09:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_description: description or external_id exceeds its length limit.\n\nKnown error: invalid_return_url: return_url must be an HTTPS URL without userinfo.\n\nKnown error: invalid_assets: assets must be a non-empty list of distinct {chain_id, token} pairs, sent without chain_id and token.\n\nKnown error: merchant_disabled: The merchant is disabled.\n\nKnown error: merchant_network_disabled: The selected network is disabled for this merchant.\n\nKnown error: network_disabled: The network is switched off or not running right now.\n\nKnown error: unsupported_network: The chain ID is not a network Invoise supports.\n\nKnown error: unsupported_asset: The network or token is not available for this shop.\n\nKnown error: shop_archived: The shop is archived.\n\nKnown error: asset_not_ready: The selected production asset is not ready.\n\nKnown error: network_not_ready: The selected network factory is not ready.\n\nKnown error: recipient_required: A non-zero recipient address is required.\n\nKnown error: wallet_not_ready: The selected Invoise wallet is not set up yet.\n\nKnown error: solana_setup_required: Set the shop's Solana recipient before issuing on Solana.\n\nKnown error: solana_recipient_token_account_required: The Solana recipient has no account for this token yet; receive the token there once first.\n\nKnown error: solana_bridge_unavailable: Solana payments cannot be bridged into the Invoise wallet right now.\n\nKnown error: solana_sandbox_unavailable: Solana is not available in a sandbox shop.\n\nKnown error: tron_setup_required: Set the shop's Tron recipient before issuing on Tron.\n\nKnown error: invalid_tron_recipient: The Tron recipient belongs to Invoise and cannot receive payouts.\n\nKnown error: tron_bridge_unavailable: Tron payments cannot reach the Invoise wallet; keep Tron on its own address.\n\nKnown error: deposit_amount_must_be_empty: Free-amount deposits cannot contain a positive amount.\n\nKnown error: invalid_expires_in: expires_in must be 1d, 7d, 30d, 180d or 365d, and only invoices accept it.\n\nKnown error: deposit_address_limit_reached: The merchant has reached its limit of active deposit addresses for this network family.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "For a free-amount deposit omit amount or send \"0\".",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDepositRequest"
              },
              "example": {
                "chain_id": 12345,
                "token": "0x6666666666666666666666666666666666666666",
                "description": "Order 1042",
                "external_id": "order-1042",
                "return_url": "https://merchant.example/paid"
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/deposits",
        "x-auth": {
          "kind": "session-or-write-key",
          "apiKeyScopes": [
            "write"
          ]
        }
      },
      "get": {
        "operationId": "listDeposits",
        "summary": "List confirmed incoming transfers",
        "description": "This route always returns {items,next_cursor}. It is a journal of confirmed incoming transfers, including late transfers into invoices.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Invoices and deposits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DepositHistoryPage"
                },
                "example": {
                  "items": [
                    {
                      "id": "event-1042",
                      "issuance_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
                      "public_id": "pay_7Jm2Qp8K4dR6sT9v",
                      "issuance_kind": "invoice",
                      "description": "Order 1042",
                      "chain_id": 12345,
                      "token": "0x6666666666666666666666666666666666666666",
                      "token_decimals": 6,
                      "amount": "10000000",
                      "tx_hash": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
                      "sender": "0x5555555555555555555555555555555555555555",
                      "recipient": "0x3333333333333333333333333333333333333333",
                      "occurred_at": "2026-09-19T09:05:00Z",
                      "block_number": 12345678,
                      "log_index": 2,
                      "status": "confirmed"
                    }
                  ],
                  "next_cursor": ""
                }
              }
            }
          },
          "400": {
            "description": "invalid_query: The search query is too long.\n\nKnown error: invalid_limit: limit must be between 1 and 100.\n\nKnown error: invalid_cursor: The cursor is malformed or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_query",
                    "message": "invalid_query"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "query",
            "name": "q",
            "required": false,
            "description": "Case-insensitive search over issuance and transfer fields.",
            "schema": {
              "type": "string"
            },
            "example": "order-1042"
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Page size, 1–100.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "example": 25
          },
          {
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Opaque cursor returned as next_cursor.",
            "schema": {
              "type": "string"
            },
            "example": "cursor-demo-1"
          }
        ],
        "x-legacy-path": "/projects/{project}/deposits",
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      }
    },
    "/shops/{shop_id}/deposits/{id}": {
      "patch": {
        "operationId": "setDepositEnabled",
        "summary": "Enable or disable a deposit checkout",
        "description": "This changes checkout availability only. Watches, incoming accounting, and settlement continue for a disabled deposit. For a group, send the group id: every address is switched together. An option's own id returns issuance_in_group.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Invoices and deposits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DepositActivationResponse"
                },
                "example": {
                  "id": "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
                  "enabled": false,
                  "disabled_at": "2026-09-19T09:20:00Z"
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: enabled_required: enabled is required.\n\nKnown error: invalid_deposit: The deposit identifier is invalid.\n\nKnown error: deposit_not_found: The deposit does not exist in this shop.\n\nKnown error: not_a_deposit: The issuance is not a deposit.\n\nKnown error: issuance_in_group: This invoice or deposit is one option of a group; cancel or switch the group by its id.\n\nKnown error: shop_archived: The shop is archived.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "Deposit issuance UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "cccccccc-cccc-4ccc-8ccc-cccccccccccc"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DepositActivationRequest"
              },
              "example": {
                "enabled": false
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/deposits/{id}",
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    },
    "/shops/{shop_id}/issuances/{id}": {
      "get": {
        "operationId": "getIssuance",
        "summary": "Read an invoice or deposit",
        "description": "Poll this endpoint after a 202 create response. Statuses are registering, open, funded, settled, and reconciling. received is cumulative confirmed incoming amount, not current address balance. For a group, the status is that of the option that paid it, and paid_issuance_id names that option.\n\nAuthentication: Session or an `ivk_` key with the exact `read` scope.\n\nScope: `read`",
        "tags": [
          "Invoices and deposits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "received is cumulative confirmed incoming amount in base units; transfers contains at most the latest 10 confirmed transfer rows. A group id returns group: true with every option in options.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PaymentDetail"
                    },
                    {
                      "$ref": "#/components/schemas/IssuanceGroup"
                    }
                  ]
                },
                "examples": {
                  "example1": {
                    "value": {
                      "id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
                      "shop_id": "11111111-1111-4111-8111-111111111111",
                      "public_id": "pay_7Jm2Qp8K4dR6sT9v",
                      "kind": "invoice",
                      "chain_id": 12345,
                      "token": "0x6666666666666666666666666666666666666666",
                      "amount": "10000000",
                      "address": "0x3333333333333333333333333333333333333333",
                      "status": "funded",
                      "description": "Order 1042",
                      "created_at": "2026-09-19T09:00:00Z",
                      "cancelled_at": null,
                      "disabled_at": null,
                      "expires_at": "2026-10-19T09:00:00Z",
                      "payment_url": "https://pay.invoise.me/pay_7Jm2Qp8K4dR6sT9v",
                      "family": "evm",
                      "recipient": "0x4444444444444444444444444444444444444444",
                      "delegate": "0x0000000000000000000000000000000000000000",
                      "tariff": "313855086777256854443215904919737715838717802223201725644800",
                      "salt": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                      "factory": "0x1111111111111111111111111111111111111111",
                      "token_decimals": 6,
                      "received": "10000000",
                      "deposit_tx_hash": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
                      "payout_tx_hash": null,
                      "transfers": [
                        {
                          "tx_hash": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
                          "amount": "10000000",
                          "occurred_at": "2026-09-19T09:05:00Z",
                          "direction": "incoming"
                        }
                      ]
                    }
                  },
                  "example2": {
                    "value": {
                      "group": true,
                      "id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
                      "shop_id": "11111111-1111-4111-8111-111111111111",
                      "public_id": "pay_9Tq3Wm5Rz8Kd2YpL",
                      "kind": "invoice",
                      "amount": "10.5",
                      "description": "Order 1043",
                      "external_id": "order-1043",
                      "status": "open",
                      "paid_issuance_id": null,
                      "created_at": "2026-09-19T09:00:00Z",
                      "cancelled_at": null,
                      "disabled_at": null,
                      "expires_at": "2026-10-19T09:00:00Z",
                      "payment_url": "https://pay.invoise.me/pay_9Tq3Wm5Rz8Kd2YpL",
                      "options": [
                        {
                          "id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
                          "shop_id": "11111111-1111-4111-8111-111111111111",
                          "public_id": "pay_4Kp8Vn2Lm6Qr9XsT",
                          "kind": "invoice",
                          "chain_id": 12345,
                          "token": "0x6666666666666666666666666666666666666666",
                          "amount": "10500000",
                          "address": "0x3333333333333333333333333333333333333333",
                          "status": "open",
                          "description": "Order 1042",
                          "created_at": "2026-09-19T09:00:00Z",
                          "cancelled_at": null,
                          "disabled_at": null,
                          "expires_at": "2026-10-19T09:00:00Z",
                          "family": "evm",
                          "recipient": "0x4444444444444444444444444444444444444444",
                          "delegate": "0x0000000000000000000000000000000000000000",
                          "tariff": "313855086777256854443215904919737715838717802223201725644800",
                          "salt": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
                          "factory": "0x1111111111111111111111111111111111111111",
                          "token_decimals": 6,
                          "received": "0",
                          "deposit_tx_hash": null,
                          "payout_tx_hash": null,
                          "transfers": []
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "not_found: The requested resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "not_found",
                    "message": "not_found"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "Issuance UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"
          }
        ],
        "x-legacy-path": "/projects/{project}/issuances/{id}",
        "x-auth": {
          "kind": "session-or-read-key",
          "apiKeyScopes": [
            "read"
          ]
        }
      }
    },
    "/shops/{shop_id}/keys": {
      "get": {
        "operationId": "listApiKeys",
        "summary": "List shop API keys",
        "description": "This read endpoint intentionally requires the exact write scope for API-key callers because the source checks projectPrincipal(write=true). A write scope does not imply read on other endpoints.\n\nAuthentication: Session or an `ivk_` key with the exact `write` scope. `write` does not imply `read`.\n\nScope: `write`",
        "tags": [
          "API keys"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Key"
                  }
                },
                "example": [
                  {
                    "id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
                    "name": "Checkout reader",
                    "prefix": "ivk_AbCdEf12",
                    "scopes": [
                      "read"
                    ],
                    "allowed_ips": [
                      "203.0.113.10"
                    ],
                    "revoked_at": null,
                    "disabled_at": null,
                    "last_used_at": "2026-09-19T09:30:00Z",
                    "created_at": "2026-09-18T12:00:00Z"
                  }
                ]
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          }
        ],
        "x-legacy-path": "/projects/{project}/keys",
        "x-auth": {
          "kind": "session-or-write-key",
          "apiKeyScopes": [
            "write"
          ]
        }
      },
      "post": {
        "operationId": "createApiKey",
        "summary": "Create a shop API key",
        "description": "Only an owner/developer session can create a key, and fresh-auth checks apply. The ivk_ token is returned once; store it immediately. API keys cannot create keys.\n\nAuthentication: Owner or developer session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "API keys"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyCreateResponse"
                },
                "example": {
                  "id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
                  "token": "ivk_demo_secret_shown_once",
                  "name": "Checkout reader",
                  "scopes": [
                    "read"
                  ],
                  "allowed_ips": [
                    "203.0.113.10"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_key: The key name or key identifier is invalid.\n\nKnown error: invalid_scope: Scopes may contain only read and write.\n\nKnown error: invalid_allowed_ips: An allowlist entry is not a valid address or CIDR.\n\nKnown error: too_many_allowed_ips: At most 64 allowlist entries are accepted.\n\nKnown error: api_key_limit_reached: The shop already has 10 API keys that are not revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KeyCreateRequest"
              },
              "example": {
                "name": "Checkout reader",
                "scopes": [
                  "read"
                ],
                "allowed_ips": [
                  "203.0.113.10"
                ]
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/keys",
        "x-auth": {
          "kind": "session-owner-or-developer",
          "apiKeyScopes": [],
          "sessionOnly": true,
          "fresh": true
        }
      }
    },
    "/shops/{shop_id}/keys/{id}": {
      "patch": {
        "operationId": "updateApiKey",
        "summary": "Update API key metadata or state",
        "description": "Omitted properties remain unchanged. Updating never rotates or returns the token. A revoked key cannot be re-enabled or edited.\n\nAuthentication: Owner or developer session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "API keys"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyUpdateResponse"
                },
                "example": {
                  "id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd",
                  "name": "Checkout reader",
                  "scopes": [
                    "read"
                  ],
                  "allowed_ips": [],
                  "enabled": true,
                  "disabled_at": null,
                  "revoked_at": null
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_key: The key name or key identifier is invalid.\n\nKnown error: invalid_key_update: At least one key property must be supplied.\n\nKnown error: invalid_scope: Scopes may contain only read and write.\n\nKnown error: invalid_allowed_ips: An allowlist entry is not a valid address or CIDR.\n\nKnown error: too_many_allowed_ips: At most 64 allowlist entries are accepted.\n\nKnown error: key_not_found: The API key does not exist in this shop.\n\nKnown error: key_revoked: A revoked key cannot be re-enabled or edited.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "API key UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "dddddddd-dddd-4ddd-8ddd-dddddddddddd"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KeyUpdateRequest"
              },
              "example": {
                "enabled": true,
                "allowed_ips": []
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/keys/{id}",
        "x-auth": {
          "kind": "session-owner-or-developer",
          "apiKeyScopes": [],
          "sessionOnly": true,
          "fresh": true
        }
      },
      "delete": {
        "operationId": "revokeApiKey",
        "summary": "Revoke an API key permanently",
        "description": "Revocation is permanent. The route returns revoked: true even when the key was already revoked or does not belong to the shop.\n\nAuthentication: Owner or developer session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "API keys"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokedResponse"
                },
                "example": {
                  "revoked": true
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "API key UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "dddddddd-dddd-4ddd-8ddd-dddddddddddd"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "x-legacy-path": "/projects/{project}/keys/{id}",
        "x-auth": {
          "kind": "session-owner-or-developer",
          "apiKeyScopes": [],
          "sessionOnly": true,
          "fresh": true
        }
      }
    },
    "/shops/{shop_id}/webhooks": {
      "get": {
        "operationId": "listWebhooks",
        "summary": "List webhook endpoints",
        "description": "This read endpoint requires the exact write scope for API-key callers. Supported exact events: transfer.observed, transfer.confirmed, transfer.reverted, invoice.closed, invoice.cancelled, payout.sent, payout.confirmed, payout.reverted, payout.failed; group filters transfer, invoice, payout. gas.wait and sweep.failed are accepted as filters but are internal signals that are never delivered.\n\nAuthentication: Session or an `ivk_` key with the exact `write` scope. `write` does not imply `read`.\n\nScope: `write`",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Webhook"
                  }
                },
                "example": [
                  {
                    "id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
                    "url": "https://merchant.example/hooks/invoise",
                    "filters": [
                      "transfer.confirmed",
                      "invoice.cancelled"
                    ],
                    "enabled": true
                  }
                ]
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          }
        ],
        "x-legacy-path": "/projects/{project}/webhooks",
        "x-auth": {
          "kind": "session-or-write-key",
          "apiKeyScopes": [
            "write"
          ]
        }
      },
      "post": {
        "operationId": "createWebhook",
        "summary": "Create a webhook endpoint",
        "description": "Returns 201 with {id,secret,url,filters}. The secret is saved for signing and is not returned by list or update. Supported exact events: transfer.observed, transfer.confirmed, transfer.reverted, invoice.closed, invoice.cancelled, payout.sent, payout.confirmed, payout.reverted, payout.failed; group filters transfer, invoice, payout. gas.wait and sweep.failed are accepted as filters but are internal signals that are never delivered.\n\nAuthentication: Session or an `ivk_` key with the exact `write` scope. `write` does not imply `read`.\n\nScope: `write`",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "The secret is generated and saved; save this returned value for signature verification.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookCreateResponse"
                },
                "example": {
                  "id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
                  "secret": "whsec_demo_secret_returned_once",
                  "url": "https://merchant.example/hooks/invoise",
                  "filters": [
                    "transfer.confirmed",
                    "invoice.cancelled"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_webhook_destination: The webhook URL must be HTTPS and resolve to a public destination.\n\nKnown error: invalid_webhook_filters: One or more webhook filters are unsupported.\n\nKnown error: too_many_filters: At most 32 webhook filters are accepted.\n\nKnown error: webhook_limit_reached: The shop already has 10 webhook endpoints.\n\nKnown error: json_content_type_required: The request Content-Type must be application/json.\n\nKnown error: invalid_json: The JSON body is malformed or contains unknown fields.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookCreateRequest"
              },
              "example": {
                "url": "https://merchant.example/hooks/invoise",
                "filters": [
                  "transfer.confirmed",
                  "invoice.cancelled"
                ]
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/webhooks",
        "x-auth": {
          "kind": "session-or-write-key",
          "apiKeyScopes": [
            "write"
          ]
        }
      }
    },
    "/shops/{shop_id}/webhooks/{id}": {
      "patch": {
        "operationId": "updateWebhook",
        "summary": "Update a webhook endpoint",
        "description": "Omitted fields remain unchanged. Re-enabling an endpoint is subject to shop availability checks.\n\nAuthentication: Session or an `ivk_` key with the exact `write` scope. `write` does not imply `read`.\n\nScope: `write`",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdatedResponse"
                },
                "example": {
                  "updated": true
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: invalid_webhook_destination: The webhook URL must be HTTPS and resolve to a public destination.\n\nKnown error: invalid_webhook_filters: One or more webhook filters are unsupported.\n\nKnown error: too_many_filters: At most 32 webhook filters are accepted.\n\nKnown error: not_found: The requested resource was not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "Webhook endpoint UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookUpdateRequest"
              },
              "example": {
                "enabled": true
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/webhooks/{id}",
        "x-auth": {
          "kind": "session-or-write-key",
          "apiKeyScopes": [
            "write"
          ]
        }
      }
    },
    "/shops/{shop_id}/deliveries": {
      "get": {
        "operationId": "listWebhookDeliveries",
        "summary": "List webhook deliveries",
        "description": "Inspect delivery state and attempts. API-key callers need write, matching the source authorization check.\n\nAuthentication: Session or an `ivk_` key with the exact `write` scope. `write` does not imply `read`.\n\nScope: `write`",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Without limit or cursor the response is an array; supplying either returns {items,next_cursor}.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Delivery"
                      }
                    },
                    {
                      "$ref": "#/components/schemas/DeliveryPage"
                    }
                  ]
                },
                "examples": {
                  "example1": {
                    "value": [
                      {
                        "id": "ffffffff-ffff-4fff-8fff-ffffffffffff",
                        "event_id": "12121212-1212-4121-8121-121212121212",
                        "event_kind": "transfer.confirmed",
                        "endpoint_id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
                        "status": "delivered",
                        "generation": 1,
                        "created_at": "2026-09-19T09:05:01Z",
                        "deadline_at": "2026-09-22T09:05:01Z",
                        "attempts": [
                          {
                            "id": "13131313-1313-4131-8131-131313131313",
                            "status_code": 200,
                            "error_code": "",
                            "created_at": "2026-09-19T09:05:02Z"
                          }
                        ]
                      }
                    ]
                  },
                  "example2": {
                    "value": {
                      "items": [
                        {
                          "id": "ffffffff-ffff-4fff-8fff-ffffffffffff",
                          "event_id": "12121212-1212-4121-8121-121212121212",
                          "event_kind": "transfer.confirmed",
                          "endpoint_id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
                          "status": "delivered",
                          "generation": 1,
                          "created_at": "2026-09-19T09:05:01Z",
                          "deadline_at": "2026-09-22T09:05:01Z",
                          "attempts": [
                            {
                              "id": "13131313-1313-4131-8131-131313131313",
                              "status_code": 200,
                              "error_code": "",
                              "created_at": "2026-09-19T09:05:02Z"
                            }
                          ]
                        }
                      ],
                      "next_cursor": ""
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "invalid_limit: limit must be between 1 and 100.\n\nKnown error: invalid_cursor: The cursor is malformed or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "invalid_limit",
                    "message": "invalid_limit"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "When present, switches to cursor pagination; 1–100.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "example": 25
          },
          {
            "in": "query",
            "name": "cursor",
            "required": false,
            "description": "Opaque cursor returned as next_cursor.",
            "schema": {
              "type": "string"
            },
            "example": "cursor-demo-1"
          }
        ],
        "x-legacy-path": "/projects/{project}/deliveries",
        "x-auth": {
          "kind": "session-or-write-key",
          "apiKeyScopes": [
            "write"
          ]
        }
      }
    },
    "/shops/{shop_id}/deliveries/{id}/replay": {
      "post": {
        "operationId": "replayWebhookDelivery",
        "summary": "Replay a stored webhook delivery",
        "description": "Only delivered or failed deliveries with a deliverable event can be queued again. The stored event envelope is reused.\n\nAuthentication: Session or an `ivk_` key with the exact `write` scope. `write` does not imply `read`.\n\nScope: `write`",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReplayResponse"
                },
                "example": {
                  "queued": true
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: delivery_not_replayable: This delivery is not in a replayable state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "Delivery UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "ffffffff-ffff-4fff-8fff-ffffffffffff"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "x-legacy-path": "/projects/{project}/deliveries/{id}/replay",
        "x-auth": {
          "kind": "session-or-write-key",
          "apiKeyScopes": [
            "write"
          ]
        }
      }
    },
    "/shops/{shop_id}/sandbox/simulate": {
      "post": {
        "operationId": "simulateSandboxEvent",
        "summary": "Simulate a sandbox payment event",
        "description": "Use a sandbox shop only. The request must include issuance_id, kind, and amount; the empty object shown by older guides is invalid. Reuse the same Idempotency-Key for an ambiguous retry.\n\nAuthentication: Session or an `ivk_` key with the exact `write` scope. `write` does not imply `read`.\n\nScope: `write`",
        "tags": [
          "Sandbox"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Transfer and invoice events return {accepted:true}; gas.wait and sweep.failed return {simulated:true}. gas.wait and sweep.failed only change the pending payout's state; they send no webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/SandboxAcceptedResponse"
                    },
                    {
                      "$ref": "#/components/schemas/SandboxOperationResponse"
                    }
                  ]
                },
                "examples": {
                  "example1": {
                    "value": {
                      "accepted": true
                    }
                  },
                  "example2": {
                    "value": {
                      "simulated": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: sandbox_only: The route is available only for a sandbox shop.\n\nKnown error: issuance_not_found: The issuance does not exist in this sandbox shop.\n\nKnown error: sandbox_amount_limit: A sandbox invoice or simulated transfer can be at most 10,000 tokens.\n\nKnown error: invalid_event_kind: The simulation kind is unsupported.\n\nKnown error: invalid_watch: The issuance watch identifier is invalid.\n\nKnown error: event_watch_mismatch: The simulated event does not match the issuance watch.\n\nKnown error: invoice_not_funded: invoice.closed requires a funded or settled invoice.\n\nKnown error: reversal_reference_required: A reverted transfer must name its original event.\n\nKnown error: reversal_reference_missing: The referenced original event does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Sandbox shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "An empty {} body is invalid; issuance_id, kind, and amount are required.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxSimulateRequest"
              },
              "example": {
                "issuance_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
                "kind": "transfer.confirmed",
                "amount": "10000000"
              }
            }
          }
        },
        "x-legacy-path": "/projects/{project}/sandbox/simulate",
        "x-auth": {
          "kind": "session-or-write-key",
          "apiKeyScopes": [
            "write"
          ]
        }
      }
    },
    "/shops/{shop_id}/sandbox/reset": {
      "post": {
        "operationId": "resetSandbox",
        "summary": "Reset sandbox financial state",
        "description": "Deletes sandbox issuances, events, operations, accounting, and webhook deliveries while retaining durable idempotency records. Only an owner session may reset.\n\nAuthentication: Owner session only; API keys are rejected. A fresh MFA-authenticated session is required when MFA is configured.\n\nScope: Merchant/shop owner role.",
        "tags": [
          "Sandbox"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxResetResponse"
                },
                "example": {
                  "reset": true
                }
              }
            }
          },
          "400": {
            "description": "idempotency_key_required: Mutating requests require a non-empty Idempotency-Key of at most 128 bytes.\n\nKnown error: sandbox_only: The route is available only for a sandbox shop.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_key_required",
                    "message": "idempotency_key_required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: Authentication is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "unauthorized",
                    "message": "unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "mfa_required: A fresh MFA-authenticated session is required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "mfa_required",
                    "message": "mfa_required"
                  }
                }
              }
            }
          },
          "409": {
            "description": "idempotency_conflict: The key was already used with a different request body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "idempotency_conflict"
                  }
                }
              }
            }
          },
          "500": {
            "description": "internal_error: The platform could not complete the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "internal_error",
                    "message": "internal_error"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "shop_id",
            "required": true,
            "description": "Sandbox shop UUID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-1111-4111-8111-111111111111"
          },
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "description": "Durable idempotency key; reuse it after an ambiguous result and do not change the request body.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "api-demo-20260919-01"
          }
        ],
        "x-legacy-path": "/projects/{project}/sandbox/reset",
        "x-auth": {
          "kind": "session-owner",
          "apiKeyScopes": [],
          "fresh": true
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Session bearer token or shop API key prefixed ivk_. Endpoint descriptions specify whether a session or exact read/write scope is required."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable machine-readable error code"
          },
          "message": {
            "type": "string",
            "description": "Human-readable message; currently equal to code"
          },
          "details": {
            "description": "Extra context for some codes: the {chain_id, token} option a multi-option request failed on, or the block reason for account_disabled"
          }
        },
        "required": [
          "code",
          "message"
        ],
        "additionalProperties": false
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/Error"
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "Token": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "description": "Token address from GET /networks: the contract on EVM and Tron, the mint on Solana"
          },
          "symbol": {
            "type": "string",
            "description": "Token symbol"
          },
          "decimals": {
            "type": "integer",
            "description": "Token decimals",
            "minimum": 0
          },
          "status": {
            "type": "string",
            "description": "Asset readiness status",
            "enum": [
              "ready",
              "pending"
            ]
          },
          "error_code": {
            "type": "string",
            "description": "Asset readiness error, when present"
          },
          "icon_url": {
            "type": "string",
            "description": "Content-addressed token icon URL"
          },
          "icon_custom": {
            "type": "boolean",
            "description": "Whether the icon is merchant-managed"
          }
        },
        "required": [
          "address",
          "symbol",
          "decimals"
        ],
        "additionalProperties": false
      },
      "Network": {
        "type": "object",
        "properties": {
          "family": {
            "type": "string",
            "description": "Network family; absent or evm for EVM networks",
            "enum": [
              "evm",
              "solana",
              "tron"
            ]
          },
          "solana": {
            "type": "object",
            "properties": {
              "genesis_hash": {
                "type": "string",
                "description": "Solana genesis hash"
              },
              "operator": {
                "type": "string",
                "description": "Invoise operator wallet"
              },
              "treasury": {
                "type": "string",
                "description": "Invoise treasury wallet"
              }
            },
            "additionalProperties": true
          },
          "tron": {
            "type": "object",
            "properties": {},
            "additionalProperties": true
          },
          "chain_id": {
            "type": "integer",
            "description": "Network ID: the EVM chain ID, or the ID Invoise assigns to a Solana or Tron network",
            "minimum": 1
          },
          "name": {
            "type": "string",
            "description": "Network display name"
          },
          "native_symbol": {
            "type": "string",
            "description": "Native gas token symbol"
          },
          "explorer_url": {
            "type": "string",
            "description": "Block explorer base URL",
            "format": "uri"
          },
          "main_factory": {
            "type": "string",
            "description": "EVM deposit factory; holds the Invoise treasury on Solana and Tron"
          },
          "invoice_factory": {
            "type": "string",
            "description": "EVM invoice factory; holds the Invoise treasury on Solana and Tron"
          },
          "start_block": {
            "type": "integer",
            "description": "Indexer start block",
            "minimum": 1
          },
          "tokens": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Token"
            }
          },
          "minimum_payment": {
            "type": "string",
            "description": "Smallest invoice amount this network accepts, in whole tokens; a smaller amount returns amount_below_minimum"
          },
          "wallet_bridge": {
            "type": "boolean",
            "description": "Merchant list only: Solana payments of a shop paying into an Invoise wallet can be bridged into it"
          }
        },
        "required": [
          "chain_id",
          "name",
          "main_factory",
          "invoice_factory",
          "start_block",
          "tokens"
        ],
        "additionalProperties": false
      },
      "Principal": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "description": "Authenticated user UUID",
            "format": "uuid"
          },
          "onboarding_required": {
            "type": "boolean"
          },
          "mfa_required": {
            "type": "boolean"
          },
          "mfa_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "user_id",
          "onboarding_required",
          "mfa_required"
        ],
        "additionalProperties": false
      },
      "MeSession": {
        "type": "object",
        "properties": {
          "user": {
            "$ref": "#/components/schemas/Principal"
          },
          "csrf": {
            "type": "string",
            "description": "CSRF token for cookie-authenticated browser mutations"
          }
        },
        "required": [
          "user",
          "csrf"
        ],
        "additionalProperties": false
      },
      "ProfilePreferences": {
        "type": "object",
        "properties": {
          "theme": {
            "type": "string",
            "description": "Theme preference",
            "enum": [
              "dark",
              "light",
              "system"
            ]
          },
          "language": {
            "type": "string",
            "description": "UI language",
            "enum": [
              "en",
              "ru",
              "de",
              "es",
              "pt-BR",
              "uk"
            ]
          }
        },
        "required": [
          "theme",
          "language"
        ],
        "additionalProperties": false
      },
      "Profile": {
        "type": "object",
        "properties": {
          "display_name": {
            "type": "string",
            "description": "Display name"
          },
          "preferences": {
            "$ref": "#/components/schemas/ProfilePreferences"
          },
          "avatar_url": {
            "type": "string",
            "description": "Inline PNG data URL, or empty string"
          },
          "created_at": {
            "type": "string",
            "description": "Account creation timestamp",
            "format": "date-time"
          }
        },
        "required": [
          "display_name",
          "preferences",
          "avatar_url",
          "created_at"
        ],
        "additionalProperties": false
      },
      "ProfilePatch": {
        "type": "object",
        "properties": {
          "display_name": {
            "type": "string",
            "description": "Display name; omitted values are decoded as an empty string"
          },
          "preferences": {
            "$ref": "#/components/schemas/ProfilePreferences"
          }
        },
        "required": [
          "preferences"
        ],
        "additionalProperties": false
      },
      "ProfileAvatarRequest": {
        "type": "object",
        "properties": {
          "image_base64": {
            "type": "string",
            "description": "Base64 encoded PNG or JPEG image"
          }
        },
        "required": [
          "image_base64"
        ],
        "additionalProperties": false
      },
      "AvatarResponse": {
        "type": "object",
        "properties": {
          "avatar_url": {
            "type": "string",
            "description": "Inline PNG data URL"
          }
        },
        "required": [
          "avatar_url"
        ],
        "additionalProperties": false
      },
      "OkResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ],
        "additionalProperties": false
      },
      "CompletedResponse": {
        "type": "object",
        "properties": {
          "completed": {
            "type": "boolean"
          }
        },
        "required": [
          "completed"
        ],
        "additionalProperties": false
      },
      "OnboardingRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "First merchant name",
            "minLength": 1,
            "maxLength": 100
          },
          "email": {
            "type": "string",
            "description": "The human owner's email. Required when the account has only a wallet sign-in; it becomes a sign-in method of the same account",
            "format": "email"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "PasskeySummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Hex encoded credential ID"
          },
          "name": {
            "type": "string",
            "description": "Passkey display name"
          },
          "created_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "created_at"
        ],
        "additionalProperties": false
      },
      "ProfileSecurity": {
        "type": "object",
        "properties": {
          "totp": {
            "type": "boolean"
          },
          "passkeys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PasskeySummary"
            }
          }
        },
        "required": [
          "totp",
          "passkeys"
        ],
        "additionalProperties": false
      },
      "Identity": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identity UUID",
            "format": "uuid"
          },
          "provider": {
            "type": "string",
            "description": "Identity provider",
            "enum": [
              "email",
              "google",
              "wallet"
            ]
          },
          "label": {
            "type": "string",
            "description": "Provider label"
          }
        },
        "required": [
          "id",
          "provider",
          "label"
        ],
        "additionalProperties": false
      },
      "Merchant": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Merchant UUID",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Merchant name"
          },
          "role": {
            "type": "string",
            "description": "Effective merchant-wide role"
          },
          "shop_limit": {
            "type": "integer",
            "description": "Active shop quota",
            "minimum": 0
          },
          "shop_count": {
            "type": "integer",
            "description": "Active shop count",
            "minimum": 0
          },
          "project_limit": {
            "type": "integer",
            "description": "Legacy alias of shop_limit",
            "minimum": 0
          },
          "project_count": {
            "type": "integer",
            "description": "Legacy alias of shop_count",
            "minimum": 0
          }
        },
        "required": [
          "id",
          "name",
          "role",
          "shop_limit",
          "shop_count",
          "project_limit",
          "project_count"
        ],
        "additionalProperties": false
      },
      "PayoutWallet": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "description": "Member whose Invoise wallet receives the payouts",
            "format": "uuid"
          },
          "display_name": {
            "type": "string",
            "description": "Member display name"
          },
          "ready": {
            "type": "boolean",
            "description": "Whether the wallet is set up; issuing waits for it"
          },
          "avatar_url": {
            "type": "string",
            "description": "Team avatar URL, or empty string"
          }
        },
        "required": [
          "user_id",
          "display_name",
          "ready",
          "avatar_url"
        ],
        "additionalProperties": false
      },
      "PayoutWalletOption": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "description": "Member whose Invoise wallet can receive the payouts",
            "format": "uuid"
          },
          "display_name": {
            "type": "string",
            "description": "Member display name"
          },
          "ready": {
            "type": "boolean",
            "description": "Whether the wallet is set up"
          },
          "avatar_url": {
            "type": "string",
            "description": "Team avatar URL, or empty string"
          },
          "self": {
            "type": "boolean",
            "description": "The caller's own wallet; listed first, even before it is set up"
          }
        },
        "required": [
          "user_id",
          "display_name",
          "ready",
          "avatar_url",
          "self"
        ],
        "additionalProperties": false
      },
      "Shop": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Shop UUID",
            "format": "uuid"
          },
          "shop_id": {
            "type": "string",
            "description": "Alias of id",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Shop name"
          },
          "sandbox": {
            "type": "boolean"
          },
          "recipient": {
            "type": "string",
            "description": "EVM payout address; empty when payout_target is wallet"
          },
          "delegate": {
            "type": "string",
            "description": "EVM address",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "archived": {
            "type": "boolean"
          },
          "settings_version": {
            "type": "integer",
            "description": "Monotonic settings version",
            "minimum": 0
          },
          "payout_target": {
            "type": "string",
            "description": "Where EVM payouts go: recipient address or an Invoise wallet",
            "enum": [
              "address",
              "wallet"
            ]
          },
          "payout_wallet_user_id": {
            "type": "string",
            "description": "Wallet owner when payout_target is wallet",
            "format": "uuid"
          },
          "payout_wallet": {
            "$ref": "#/components/schemas/PayoutWallet"
          },
          "solana_recipient": {
            "type": "string",
            "description": "Solana payout wallet; empty until set"
          },
          "solana_enabled": {
            "type": "boolean",
            "description": "The merchant can use a Solana network"
          },
          "solana_payout_target": {
            "type": "string",
            "description": "Where Solana payments go",
            "enum": [
              "address",
              "wallet"
            ]
          },
          "solana_payout_wallet_user_id": {
            "type": "string",
            "description": "Wallet owner when solana_payout_target is wallet",
            "format": "uuid"
          },
          "solana_payout_wallet": {
            "$ref": "#/components/schemas/PayoutWallet"
          },
          "tron_recipient": {
            "type": "string",
            "description": "Tron payout wallet; empty until set"
          },
          "tron_enabled": {
            "type": "boolean",
            "description": "The merchant can use a Tron network"
          },
          "tron_payout_target": {
            "type": "string",
            "description": "Where Tron payments go",
            "enum": [
              "address",
              "wallet"
            ]
          },
          "tron_payout_wallet_user_id": {
            "type": "string",
            "description": "Wallet owner when tron_payout_target is wallet",
            "format": "uuid"
          },
          "tron_payout_wallet": {
            "$ref": "#/components/schemas/PayoutWallet"
          },
          "tron_bridge_ready": {
            "type": "boolean",
            "description": "Tron payments can reach an Invoise wallet"
          }
        },
        "required": [
          "id",
          "shop_id",
          "name",
          "sandbox",
          "recipient",
          "delegate",
          "archived",
          "settings_version",
          "payout_target",
          "solana_recipient",
          "solana_enabled",
          "solana_payout_target",
          "tron_recipient",
          "tron_enabled",
          "tron_payout_target",
          "tron_bridge_ready"
        ],
        "additionalProperties": false
      },
      "CreateShopRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Shop name",
            "minLength": 1,
            "maxLength": 100
          },
          "sandbox": {
            "type": "boolean",
            "description": "Create the merchant's single sandbox shop"
          },
          "payout_target": {
            "type": "string",
            "description": "address (default) pays the recipient; wallet pays into a member's Invoise wallet and must be sent without recipient",
            "enum": [
              "address",
              "wallet"
            ]
          },
          "payout_wallet_user_id": {
            "type": "string",
            "description": "Member whose wallet receives the payouts when payout_target is wallet; defaults to the caller",
            "format": "uuid"
          },
          "recipient": {
            "type": "string",
            "description": "EVM address",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "delegate": {
            "type": "string",
            "description": "EVM address",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "ShopCreateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Shop UUID",
            "format": "uuid"
          },
          "shop_id": {
            "type": "string",
            "description": "Alias of id",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Shop name"
          },
          "sandbox": {
            "type": "boolean"
          },
          "recipient": {
            "type": "string",
            "description": "EVM payout address; empty when payout_target is wallet"
          },
          "delegate": {
            "type": "string",
            "description": "EVM address",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "branding": {
            "$ref": "#/components/schemas/Branding"
          },
          "payout_target": {
            "type": "string",
            "description": "Where EVM payouts go",
            "enum": [
              "address",
              "wallet"
            ]
          },
          "payout_wallet": {
            "$ref": "#/components/schemas/PayoutWallet"
          }
        },
        "required": [
          "id",
          "shop_id",
          "name",
          "sandbox",
          "recipient",
          "delegate",
          "branding",
          "payout_target"
        ],
        "additionalProperties": false
      },
      "ShopPatchRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "New shop name",
            "maxLength": 100
          },
          "archived": {
            "type": "boolean",
            "description": "Archive or restore the shop"
          },
          "sweep_thresholds": {
            "type": "object",
            "description": "Map of chain ID strings to human token-unit thresholds",
            "additionalProperties": {
              "type": "string",
              "description": "Sweep threshold in token units"
            }
          },
          "recipient": {
            "type": "string",
            "description": "EVM address",
            "pattern": "^0x[0-9a-fA-F]{40}$"
          },
          "delegate": {
            "type": "string",
            "description": "New EVM delegate; an empty string removes it"
          },
          "payout_target": {
            "type": "string",
            "description": "address needs recipient; wallet must be sent without recipient",
            "enum": [
              "address",
              "wallet"
            ]
          },
          "payout_wallet_user_id": {
            "type": "string",
            "description": "Member whose wallet receives the payouts; defaults to the caller",
            "format": "uuid"
          },
          "solana_payout_target": {
            "type": "string",
            "description": "address pays the Solana recipient; wallet bridges Solana payments into the Invoise wallet",
            "enum": [
              "address",
              "wallet"
            ]
          },
          "solana_payout_wallet_user_id": {
            "type": "string",
            "description": "Wallet owner for Solana; defaults to the caller",
            "format": "uuid"
          },
          "tron_payout_target": {
            "type": "string",
            "description": "address pays the Tron recipient; wallet needs the Tron bridge",
            "enum": [
              "address",
              "wallet"
            ]
          },
          "tron_payout_wallet_user_id": {
            "type": "string",
            "description": "Wallet owner for Tron; defaults to the caller",
            "format": "uuid"
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "FamilyRecipient": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "description": "Payout wallet on this network family; empty until set"
          }
        },
        "required": [
          "address"
        ],
        "additionalProperties": false
      },
      "FamilyRecipientRequest": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "description": "Ordinary wallet address on this network family",
            "minLength": 1
          }
        },
        "required": [
          "address"
        ],
        "additionalProperties": false
      },
      "UpdatedResponse": {
        "type": "object",
        "properties": {
          "updated": {
            "type": "boolean"
          }
        },
        "required": [
          "updated"
        ],
        "additionalProperties": false
      },
      "Branding": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Checkout display name"
          },
          "logo": {
            "type": "string",
            "description": "Owned asset URL"
          }
        },
        "additionalProperties": true
      },
      "BrandingPatchRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Checkout display name",
            "maxLength": 100
          },
          "logo": {
            "type": "string",
            "description": "Owned asset URL"
          },
          "image_base64": {
            "type": "string",
            "description": "Base64 encoded PNG or JPEG; creates an owned PNG asset"
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "PaymentSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Issuance UUID, or the group UUID for a group row",
            "format": "uuid"
          },
          "shop_id": {
            "type": "string",
            "description": "Shop UUID",
            "format": "uuid"
          },
          "public_id": {
            "type": "string",
            "description": "Public payment identifier"
          },
          "kind": {
            "type": "string",
            "description": "Issuance kind",
            "enum": [
              "invoice",
              "deposit"
            ]
          },
          "chain_id": {
            "anyOf": [
              {
                "type": "integer",
                "description": "Network ID; null for a group row"
              },
              {
                "type": "null"
              }
            ]
          },
          "token": {
            "type": "string",
            "description": "Token address; empty for a group row"
          },
          "amount": {
            "type": "string",
            "description": "Integer amount in token base units; for a group, the decimal token amount"
          },
          "address": {
            "type": "string",
            "description": "Payment address; empty until registered and for a group row"
          },
          "status": {
            "type": "string",
            "description": "Payment status",
            "enum": [
              "registering",
              "open",
              "funded",
              "settled",
              "reconciling"
            ]
          },
          "description": {
            "type": "string",
            "description": "Merchant description"
          },
          "external_id": {
            "type": "string",
            "description": "Merchant correlation ID"
          },
          "created_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          },
          "cancelled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "disabled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "When an unpaid invoice closes; null for deposits",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "payment_url": {
            "type": "string",
            "description": "Checkout URL",
            "format": "uri"
          },
          "group": {
            "type": "boolean",
            "const": true,
            "description": "Present on a group row"
          },
          "assets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Option issuance UUID",
                  "format": "uuid"
                },
                "chain_id": {
                  "type": "integer",
                  "description": "Network ID"
                },
                "token": {
                  "type": "string",
                  "description": "Token address from GET /networks: the contract on EVM and Tron, the mint on Solana"
                },
                "token_decimals": {
                  "type": "integer",
                  "description": "Token decimals",
                  "minimum": 0
                },
                "address": {
                  "anyOf": [
                    {
                      "type": "string",
                      "description": "Address on the issuance's network: 0x hex on EVM, base58 on Solana and Tron"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              },
              "required": [
                "id",
                "chain_id",
                "token",
                "token_decimals",
                "address"
              ],
              "additionalProperties": false
            }
          },
          "paid_issuance_id": {
            "anyOf": [
              {
                "type": "string",
                "description": "Option that paid the group",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "shop_id",
          "public_id",
          "kind",
          "chain_id",
          "token",
          "amount",
          "address",
          "status",
          "description",
          "external_id",
          "created_at",
          "cancelled_at",
          "disabled_at",
          "expires_at",
          "payment_url"
        ],
        "additionalProperties": false
      },
      "PaymentDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Issuance UUID",
            "format": "uuid"
          },
          "shop_id": {
            "type": "string",
            "description": "Shop UUID",
            "format": "uuid"
          },
          "public_id": {
            "type": "string",
            "description": "Public payment identifier"
          },
          "kind": {
            "type": "string",
            "description": "Issuance kind",
            "enum": [
              "invoice",
              "deposit"
            ]
          },
          "family": {
            "type": "string",
            "description": "Network family",
            "enum": [
              "evm",
              "solana",
              "tron"
            ]
          },
          "chain_id": {
            "type": "integer",
            "description": "Network ID"
          },
          "token": {
            "type": "string",
            "description": "Token address from GET /networks: the contract on EVM and Tron, the mint on Solana"
          },
          "amount": {
            "type": "string",
            "description": "Unsigned integer amount in token base units",
            "pattern": "^[0-9]+$"
          },
          "address": {
            "anyOf": [
              {
                "type": "string",
                "description": "Address on the issuance's network: 0x hex on EVM, base58 on Solana and Tron"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "description": "Payment status",
            "enum": [
              "registering",
              "open",
              "funded",
              "settled",
              "reconciling"
            ]
          },
          "recipient": {
            "type": "string",
            "description": "Address on the issuance's network: 0x hex on EVM, base58 on Solana and Tron"
          },
          "delegate": {
            "type": "string",
            "description": "EVM delegate snapshot; empty on Solana and Tron"
          },
          "tariff": {
            "type": "string",
            "description": "Packed tariff snapshot as a decimal integer produced by Tariff.Pack"
          },
          "salt": {
            "type": "string",
            "description": "Address derivation salt"
          },
          "factory": {
            "type": "string",
            "description": "EVM factory snapshot; the Invoise treasury on Solana and Tron"
          },
          "token_decimals": {
            "type": "integer",
            "description": "Token decimals",
            "minimum": 0
          },
          "token_account": {
            "anyOf": [
              {
                "type": "string",
                "description": "Solana token account of the payment address"
              },
              {
                "type": "null"
              }
            ]
          },
          "solana_routing": {
            "anyOf": [
              {
                "type": "object",
                "properties": {},
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ]
          },
          "description": {
            "type": "string",
            "description": "Merchant description"
          },
          "created_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          },
          "cancelled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "disabled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "When an unpaid invoice closes; null for deposits",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "received": {
            "type": "string",
            "description": "Unsigned integer amount in token base units",
            "pattern": "^[0-9]+$"
          },
          "deposit_tx_hash": {
            "anyOf": [
              {
                "type": "string",
                "description": "Last confirmed incoming transaction hash"
              },
              {
                "type": "null"
              }
            ]
          },
          "payout_tx_hash": {
            "anyOf": [
              {
                "type": "string",
                "description": "Last confirmed payout transaction hash"
              },
              {
                "type": "null"
              }
            ]
          },
          "payment_url": {
            "type": "string",
            "description": "Checkout URL",
            "format": "uri"
          },
          "transfers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transfer"
            }
          }
        },
        "required": [
          "id",
          "shop_id",
          "public_id",
          "kind",
          "chain_id",
          "token",
          "amount",
          "address",
          "status",
          "recipient",
          "delegate",
          "tariff",
          "salt",
          "factory",
          "token_decimals",
          "description",
          "created_at",
          "cancelled_at",
          "disabled_at",
          "expires_at",
          "received",
          "deposit_tx_hash",
          "payout_tx_hash",
          "transfers"
        ],
        "additionalProperties": false
      },
      "IssuanceGroup": {
        "type": "object",
        "properties": {
          "group": {
            "type": "boolean",
            "const": true
          },
          "id": {
            "type": "string",
            "description": "Group UUID",
            "format": "uuid"
          },
          "shop_id": {
            "type": "string",
            "description": "Shop UUID",
            "format": "uuid"
          },
          "public_id": {
            "type": "string",
            "description": "Public payment identifier of the whole group"
          },
          "kind": {
            "type": "string",
            "description": "Issuance kind",
            "enum": [
              "invoice",
              "deposit"
            ]
          },
          "amount": {
            "type": "string",
            "description": "Decimal token amount of the invoice; empty for a deposit"
          },
          "description": {
            "type": "string",
            "description": "Merchant description"
          },
          "external_id": {
            "type": "string",
            "description": "Merchant correlation ID"
          },
          "status": {
            "type": "string",
            "description": "Status of the option that paid the group; before that registering while any option waits for its address, else open",
            "enum": [
              "registering",
              "open",
              "funded",
              "settled",
              "reconciling"
            ]
          },
          "paid_issuance_id": {
            "anyOf": [
              {
                "type": "string",
                "description": "Option that paid the group",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "created_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          },
          "cancelled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "disabled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "When an unpaid invoice closes; null for deposits",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "payment_url": {
            "type": "string",
            "description": "Checkout URL where the payer picks an option",
            "format": "uri"
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PaymentDetail"
            }
          }
        },
        "required": [
          "group",
          "id",
          "shop_id",
          "public_id",
          "kind",
          "amount",
          "status",
          "paid_issuance_id",
          "created_at",
          "cancelled_at",
          "disabled_at",
          "expires_at",
          "payment_url",
          "options"
        ],
        "additionalProperties": false
      },
      "Transfer": {
        "type": "object",
        "properties": {
          "tx_hash": {
            "type": "string",
            "description": "Transaction hash"
          },
          "amount": {
            "type": "string",
            "description": "Unsigned integer amount in token base units",
            "pattern": "^[0-9]+$"
          },
          "occurred_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          },
          "direction": {
            "type": "string",
            "description": "Transfer direction",
            "enum": [
              "incoming",
              "payout"
            ]
          }
        },
        "required": [
          "tx_hash",
          "amount",
          "occurred_at",
          "direction"
        ],
        "additionalProperties": false
      },
      "IssuanceAsset": {
        "type": "object",
        "properties": {
          "chain_id": {
            "type": "integer",
            "description": "Network ID from GET /networks",
            "minimum": 1
          },
          "token": {
            "type": "string",
            "description": "Token address from GET /networks: the contract on EVM and Tron, the mint on Solana"
          }
        },
        "required": [
          "chain_id",
          "token"
        ],
        "additionalProperties": false
      },
      "CreateInvoiceRequest": {
        "type": "object",
        "properties": {
          "chain_id": {
            "type": "integer",
            "description": "Network ID from GET /networks; omit when sending assets",
            "minimum": 1
          },
          "token": {
            "type": "string",
            "description": "Token address from GET /networks: the contract on EVM and Tron, the mint on Solana"
          },
          "assets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IssuanceAsset"
            },
            "minItems": 1,
            "description": "Offer the payer several tokens or networks; send instead of chain_id and token"
          },
          "amount": {
            "type": "string",
            "description": "Integer amount in token base units; with assets, a decimal token amount such as \"10.5\""
          },
          "expires_in": {
            "type": "string",
            "description": "How long the invoice can be paid; default 30d",
            "enum": [
              "1d",
              "7d",
              "30d",
              "180d",
              "365d"
            ]
          },
          "description": {
            "type": "string",
            "description": "Optional merchant description",
            "maxLength": 500
          },
          "external_id": {
            "type": "string",
            "description": "Optional merchant correlation ID",
            "maxLength": 200
          },
          "return_url": {
            "type": "string",
            "description": "HTTPS URL to return from checkout",
            "format": "uri"
          }
        },
        "required": [
          "amount"
        ],
        "additionalProperties": false,
        "oneOf": [
          {
            "required": [
              "chain_id",
              "token"
            ]
          },
          {
            "required": [
              "assets"
            ]
          }
        ]
      },
      "CreateDepositRequest": {
        "type": "object",
        "properties": {
          "chain_id": {
            "type": "integer",
            "description": "Network ID from GET /networks; omit when sending assets",
            "minimum": 1
          },
          "token": {
            "type": "string",
            "description": "Token address from GET /networks: the contract on EVM and Tron, the mint on Solana"
          },
          "assets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IssuanceAsset"
            },
            "minItems": 1,
            "description": "One address per option; send instead of chain_id and token"
          },
          "amount": {
            "type": "string",
            "description": "Omit or send \"0\"",
            "enum": [
              "0"
            ]
          },
          "description": {
            "type": "string",
            "description": "Optional merchant description",
            "maxLength": 500
          },
          "external_id": {
            "type": "string",
            "description": "Optional merchant correlation ID",
            "maxLength": 200
          },
          "return_url": {
            "type": "string",
            "description": "HTTPS URL to return from checkout",
            "format": "uri"
          }
        },
        "required": [],
        "additionalProperties": false,
        "oneOf": [
          {
            "required": [
              "chain_id",
              "token"
            ]
          },
          {
            "required": [
              "assets"
            ]
          }
        ]
      },
      "CreateIssuanceResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Issuance UUID",
            "format": "uuid"
          },
          "shop_id": {
            "type": "string",
            "description": "Shop UUID",
            "format": "uuid"
          },
          "public_id": {
            "type": "string",
            "description": "Public payment identifier"
          },
          "status": {
            "type": "string",
            "description": "Initial status",
            "enum": [
              "registering",
              "open"
            ]
          },
          "address": {
            "anyOf": [
              {
                "type": "string",
                "description": "Address on the issuance's network: 0x hex on EVM, base58 on Solana and Tron"
              },
              {
                "type": "null"
              }
            ]
          },
          "payment_url": {
            "type": "string",
            "description": "Checkout URL",
            "format": "uri"
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "When an unpaid invoice closes; null for deposits",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "shop_id",
          "public_id",
          "status",
          "address",
          "payment_url",
          "expires_at"
        ],
        "additionalProperties": false
      },
      "IssuanceOption": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Issuance UUID of this option",
            "format": "uuid"
          },
          "public_id": {
            "type": "string",
            "description": "Public identifier of this option"
          },
          "chain_id": {
            "type": "integer",
            "description": "Network ID"
          },
          "token": {
            "type": "string",
            "description": "Token address from GET /networks: the contract on EVM and Tron, the mint on Solana"
          },
          "token_decimals": {
            "type": "integer",
            "description": "Token decimals",
            "minimum": 0
          },
          "family": {
            "type": "string",
            "description": "Network family",
            "enum": [
              "evm",
              "solana",
              "tron"
            ]
          },
          "amount": {
            "type": "string",
            "description": "Unsigned integer amount in token base units",
            "pattern": "^[0-9]+$"
          },
          "address": {
            "anyOf": [
              {
                "type": "string",
                "description": "Address on the issuance's network: 0x hex on EVM, base58 on Solana and Tron"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "description": "Initial status",
            "enum": [
              "registering",
              "open"
            ]
          }
        },
        "required": [
          "id",
          "public_id",
          "chain_id",
          "token",
          "token_decimals",
          "family",
          "amount",
          "address",
          "status"
        ],
        "additionalProperties": false
      },
      "CreateIssuanceGroupResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Group UUID; use it to read, cancel or switch the whole group",
            "format": "uuid"
          },
          "group": {
            "type": "boolean",
            "const": true
          },
          "shop_id": {
            "type": "string",
            "description": "Shop UUID",
            "format": "uuid"
          },
          "public_id": {
            "type": "string",
            "description": "Public payment identifier of the group"
          },
          "status": {
            "type": "string",
            "description": "registering while any option waits for its address, else open",
            "enum": [
              "registering",
              "open"
            ]
          },
          "payment_url": {
            "type": "string",
            "description": "Checkout URL where the payer picks an option",
            "format": "uri"
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IssuanceOption"
            }
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "When an unpaid invoice closes; null for deposits",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "group",
          "shop_id",
          "public_id",
          "status",
          "payment_url",
          "options",
          "expires_at"
        ],
        "additionalProperties": false
      },
      "PaymentListPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PaymentSummary"
            }
          },
          "next_cursor": {
            "type": "string",
            "description": "Opaque cursor; empty string means no next page"
          }
        },
        "required": [
          "items",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "DepositHistoryItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Chain event ID"
          },
          "issuance_id": {
            "type": "string",
            "description": "Issuance UUID",
            "format": "uuid"
          },
          "public_id": {
            "type": "string",
            "description": "Public payment identifier"
          },
          "issuance_kind": {
            "type": "string",
            "description": "Issuance kind",
            "enum": [
              "invoice",
              "deposit"
            ]
          },
          "description": {
            "type": "string",
            "description": "Merchant description"
          },
          "chain_id": {
            "type": "integer",
            "description": "Network ID"
          },
          "token": {
            "type": "string",
            "description": "Token address from GET /networks: the contract on EVM and Tron, the mint on Solana"
          },
          "token_decimals": {
            "type": "integer",
            "description": "Token decimals",
            "minimum": 0
          },
          "amount": {
            "type": "string",
            "description": "Unsigned integer amount in token base units",
            "pattern": "^[0-9]+$"
          },
          "tx_hash": {
            "type": "string",
            "description": "Transaction hash"
          },
          "sender": {
            "type": "string",
            "description": "Address on the issuance's network: 0x hex on EVM, base58 on Solana and Tron"
          },
          "recipient": {
            "type": "string",
            "description": "Address on the issuance's network: 0x hex on EVM, base58 on Solana and Tron"
          },
          "occurred_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          },
          "block_number": {
            "type": "integer",
            "description": "Block number",
            "minimum": 0
          },
          "log_index": {
            "type": "integer",
            "description": "Log index",
            "minimum": 0
          },
          "status": {
            "type": "string",
            "description": "Journal status",
            "enum": [
              "confirmed"
            ]
          }
        },
        "required": [
          "id",
          "issuance_id",
          "public_id",
          "issuance_kind",
          "description",
          "chain_id",
          "token",
          "token_decimals",
          "amount",
          "tx_hash",
          "sender",
          "recipient",
          "occurred_at",
          "block_number",
          "log_index",
          "status"
        ],
        "additionalProperties": false
      },
      "DepositHistoryPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DepositHistoryItem"
            }
          },
          "next_cursor": {
            "type": "string",
            "description": "Opaque cursor; empty string means no next page"
          }
        },
        "required": [
          "items",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "CancelResponse": {
        "type": "object",
        "properties": {
          "cancelled": {
            "type": "boolean"
          }
        },
        "required": [
          "cancelled"
        ],
        "additionalProperties": false
      },
      "DepositActivationRequest": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          }
        },
        "required": [
          "enabled"
        ],
        "additionalProperties": false
      },
      "DepositActivationResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Deposit issuance UUID",
            "format": "uuid"
          },
          "enabled": {
            "type": "boolean"
          },
          "disabled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "enabled",
          "disabled_at"
        ],
        "additionalProperties": false
      },
      "Checkout": {
        "type": "object",
        "properties": {
          "public_id": {
            "type": "string",
            "description": "Public payment identifier"
          },
          "shop_id": {
            "type": "string",
            "description": "Shop UUID",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "description": "Issuance kind",
            "enum": [
              "invoice",
              "deposit"
            ]
          },
          "family": {
            "type": "string",
            "description": "Network family",
            "enum": [
              "evm",
              "solana",
              "tron"
            ]
          },
          "chain_id": {
            "type": "integer",
            "description": "Network ID"
          },
          "token": {
            "type": "string",
            "description": "Token address from GET /networks: the contract on EVM and Tron, the mint on Solana"
          },
          "token_decimals": {
            "type": "integer",
            "description": "Token decimals",
            "minimum": 0
          },
          "token_account": {
            "anyOf": [
              {
                "type": "string",
                "description": "Solana token account of the payment address"
              },
              {
                "type": "null"
              }
            ]
          },
          "network": {
            "type": "object",
            "properties": {},
            "additionalProperties": true
          },
          "amount": {
            "type": "string",
            "description": "Unsigned integer amount in token base units",
            "pattern": "^[0-9]+$"
          },
          "address": {
            "anyOf": [
              {
                "type": "string",
                "description": "Address on the issuance's network: 0x hex on EVM, base58 on Solana and Tron"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "description": "Payment status",
            "enum": [
              "registering",
              "open",
              "funded",
              "settled",
              "reconciling"
            ]
          },
          "cancelled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "disabled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "When an unpaid invoice closes; null for deposits",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "description": {
            "type": "string",
            "description": "Merchant description"
          },
          "return_url": {
            "type": "string",
            "description": "Configured return URL",
            "format": "uri"
          },
          "branding": {
            "$ref": "#/components/schemas/Branding"
          },
          "merchant_name": {
            "type": "string",
            "description": "Merchant name"
          },
          "sandbox": {
            "type": "boolean"
          },
          "tx_hash": {
            "type": "string",
            "description": "Last confirmed incoming transaction hash"
          },
          "received": {
            "type": "string",
            "description": "Unsigned integer amount in token base units",
            "pattern": "^[0-9]+$"
          },
          "payment_url": {
            "type": "string",
            "description": "Checkout URL",
            "format": "uri"
          }
        },
        "required": [
          "public_id",
          "shop_id",
          "kind",
          "chain_id",
          "token",
          "token_decimals",
          "network",
          "amount",
          "address",
          "status",
          "cancelled_at",
          "disabled_at",
          "expires_at",
          "description",
          "return_url",
          "branding",
          "merchant_name",
          "sandbox",
          "tx_hash",
          "received"
        ],
        "additionalProperties": false
      },
      "CheckoutGroup": {
        "type": "object",
        "properties": {
          "group": {
            "type": "boolean",
            "const": true
          },
          "public_id": {
            "type": "string",
            "description": "Public payment identifier of the group"
          },
          "shop_id": {
            "type": "string",
            "description": "Shop UUID",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "description": "Issuance kind",
            "enum": [
              "invoice",
              "deposit"
            ]
          },
          "amount": {
            "type": "string",
            "description": "Decimal token amount of the invoice; empty for a deposit"
          },
          "status": {
            "type": "string",
            "description": "Group status",
            "enum": [
              "registering",
              "open",
              "funded",
              "settled",
              "reconciling"
            ]
          },
          "cancelled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "disabled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "When an unpaid invoice closes; null for deposits",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "description": {
            "type": "string",
            "description": "Merchant description"
          },
          "return_url": {
            "type": "string",
            "description": "Configured return URL"
          },
          "branding": {
            "$ref": "#/components/schemas/Branding"
          },
          "merchant_name": {
            "type": "string",
            "description": "Merchant name"
          },
          "sandbox": {
            "type": "boolean"
          },
          "paid_public_id": {
            "anyOf": [
              {
                "type": "string",
                "description": "public_id of the option that paid the group"
              },
              {
                "type": "null"
              }
            ]
          },
          "payment_url": {
            "type": "string",
            "description": "Checkout URL",
            "format": "uri"
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Checkout"
            }
          }
        },
        "required": [
          "group",
          "public_id",
          "shop_id",
          "kind",
          "amount",
          "status",
          "cancelled_at",
          "disabled_at",
          "expires_at",
          "description",
          "return_url",
          "branding",
          "merchant_name",
          "sandbox",
          "paid_public_id",
          "payment_url",
          "options"
        ],
        "additionalProperties": false
      },
      "OverviewSeries": {
        "type": "object",
        "properties": {
          "day": {
            "type": "string",
            "description": "UTC calendar day",
            "format": "date"
          },
          "volume": {
            "type": "string",
            "description": "Received volume in display units"
          },
          "payout": {
            "type": "string",
            "description": "Payout volume in display units"
          },
          "fees": {
            "type": "string",
            "description": "Fees in display units"
          },
          "payments": {
            "type": "integer",
            "description": "Payment count",
            "minimum": 0
          }
        },
        "required": [
          "day",
          "volume",
          "payout",
          "fees",
          "payments"
        ],
        "additionalProperties": false
      },
      "OverviewStatus": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "Status bucket"
          },
          "count": {
            "type": "integer",
            "description": "Count",
            "minimum": 0
          }
        },
        "required": [
          "status",
          "count"
        ],
        "additionalProperties": false
      },
      "OverviewNetwork": {
        "type": "object",
        "properties": {
          "chain_id": {
            "type": "integer",
            "description": "EVM chain ID"
          },
          "volume": {
            "type": "string",
            "description": "Received volume"
          },
          "payments": {
            "type": "integer",
            "description": "Payment count",
            "minimum": 0
          }
        },
        "required": [
          "chain_id",
          "volume",
          "payments"
        ],
        "additionalProperties": false
      },
      "WebhookCounts": {
        "type": "object",
        "properties": {
          "delivered": {
            "type": "integer",
            "description": "Delivered count"
          },
          "failed": {
            "type": "integer",
            "description": "Failed count"
          },
          "pending": {
            "type": "integer",
            "description": "Pending count"
          }
        },
        "required": [
          "delivered",
          "failed",
          "pending"
        ],
        "additionalProperties": false
      },
      "Overview": {
        "type": "object",
        "properties": {
          "days": {
            "type": "integer",
            "description": "Window length",
            "enum": [
              7,
              30,
              90
            ]
          },
          "sandbox": {
            "type": "boolean"
          },
          "currency": {
            "type": "string",
            "description": "Display currency label"
          },
          "timezone": {
            "type": "string",
            "description": "Aggregation timezone"
          },
          "merchant_name": {
            "anyOf": [
              {
                "type": "string",
                "description": "Merchant name"
              },
              {
                "type": "null"
              }
            ]
          },
          "shops": {
            "type": "integer",
            "description": "Active shop count",
            "minimum": 0
          },
          "projects": {
            "type": "integer",
            "description": "Legacy alias of shops",
            "minimum": 0
          },
          "volume": {
            "type": "string",
            "description": "Received volume"
          },
          "payout": {
            "type": "string",
            "description": "Payout volume"
          },
          "fees": {
            "type": "string",
            "description": "Fees"
          },
          "payments": {
            "type": "integer",
            "description": "Payment count",
            "minimum": 0
          },
          "late": {
            "type": "string",
            "description": "Late receipt volume"
          },
          "excess": {
            "type": "string",
            "description": "Excess receipt volume"
          },
          "invoices": {
            "type": "integer",
            "description": "Invoice count",
            "minimum": 0
          },
          "deposits": {
            "type": "integer",
            "description": "Deposit count",
            "minimum": 0
          },
          "series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OverviewSeries"
            }
          },
          "statuses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OverviewStatus"
            }
          },
          "shops_breakdown": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Shop UUID",
                  "format": "uuid"
                },
                "name": {
                  "type": "string",
                  "description": "Shop name"
                },
                "volume": {
                  "type": "string",
                  "description": "Received volume"
                },
                "payments": {
                  "type": "integer",
                  "description": "Payment count",
                  "minimum": 0
                }
              },
              "required": [
                "id",
                "name",
                "volume",
                "payments"
              ],
              "additionalProperties": false
            }
          },
          "networks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OverviewNetwork"
            }
          },
          "webhooks": {
            "$ref": "#/components/schemas/WebhookCounts"
          }
        },
        "required": [
          "days",
          "sandbox",
          "currency",
          "timezone",
          "merchant_name",
          "shops",
          "projects",
          "volume",
          "payout",
          "fees",
          "payments",
          "late",
          "excess",
          "invoices",
          "deposits",
          "series",
          "statuses",
          "shops_breakdown",
          "networks",
          "webhooks"
        ],
        "additionalProperties": false
      },
      "Tariff": {
        "type": "object",
        "properties": {
          "bps": {
            "type": "integer",
            "description": "Tariff basis points",
            "minimum": 0,
            "maximum": 50
          },
          "minimum": {
            "type": "string",
            "description": "Unsigned integer tariff bound in 18-decimal units, independent of token decimals",
            "pattern": "^[0-9]+$"
          },
          "maximum": {
            "type": "string",
            "description": "Unsigned integer tariff bound in 18-decimal units, independent of token decimals",
            "pattern": "^[0-9]+$"
          }
        },
        "required": [
          "bps",
          "minimum",
          "maximum"
        ],
        "additionalProperties": false
      },
      "MerchantTerms": {
        "type": "object",
        "properties": {
          "chain_id": {
            "type": "integer",
            "description": "Network ID"
          },
          "family": {
            "type": "string",
            "description": "Network family",
            "enum": [
              "evm",
              "solana",
              "tron"
            ]
          },
          "name": {
            "type": "string",
            "description": "Network name"
          },
          "enabled": {
            "type": "boolean"
          },
          "invoice": {
            "$ref": "#/components/schemas/Tariff"
          },
          "deposit": {
            "$ref": "#/components/schemas/Tariff"
          }
        },
        "required": [
          "chain_id",
          "family",
          "name",
          "enabled",
          "invoice",
          "deposit"
        ],
        "additionalProperties": false
      },
      "ShopTerms": {
        "type": "object",
        "properties": {
          "chain_id": {
            "type": "integer",
            "description": "Network ID"
          },
          "family": {
            "type": "string",
            "description": "Network family",
            "enum": [
              "evm",
              "solana",
              "tron"
            ]
          },
          "name": {
            "type": "string",
            "description": "Network name"
          },
          "enabled": {
            "type": "boolean"
          },
          "minimum_sweep": {
            "type": "string",
            "description": "Minimum sweep in human-readable token units"
          },
          "maximum_sweep": {
            "type": "string",
            "description": "Maximum sweep in human-readable token units"
          },
          "sweep_threshold": {
            "type": "string",
            "description": "Configured sweep threshold in human-readable token units"
          },
          "invoice": {
            "$ref": "#/components/schemas/Tariff"
          },
          "deposit": {
            "$ref": "#/components/schemas/Tariff"
          }
        },
        "required": [
          "chain_id",
          "family",
          "name",
          "enabled",
          "minimum_sweep",
          "maximum_sweep",
          "sweep_threshold",
          "invoice",
          "deposit"
        ],
        "additionalProperties": false
      },
      "Key": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "API key UUID",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Key name"
          },
          "prefix": {
            "type": "string",
            "description": "Displayed token prefix"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Exact key scope",
              "enum": [
                "read",
                "write"
              ]
            }
          },
          "allowed_ips": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "IPv4/IPv6 address or CIDR"
            }
          },
          "revoked_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "disabled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "last_used_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "created_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "prefix",
          "scopes",
          "allowed_ips",
          "revoked_at",
          "disabled_at",
          "last_used_at",
          "created_at"
        ],
        "additionalProperties": false
      },
      "KeyCreateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Key name",
            "minLength": 1,
            "maxLength": 100
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Exact key scope",
              "enum": [
                "read",
                "write"
              ]
            }
          },
          "allowed_ips": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "IPv4/IPv6 address or CIDR"
            }
          }
        },
        "required": [
          "name",
          "scopes"
        ],
        "additionalProperties": false
      },
      "KeyCreateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "API key UUID",
            "format": "uuid"
          },
          "token": {
            "type": "string",
            "description": "Secret API key; returned only on creation",
            "pattern": "^ivk_"
          },
          "name": {
            "type": "string",
            "description": "Key name"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Exact key scope",
              "enum": [
                "read",
                "write"
              ]
            }
          },
          "allowed_ips": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Normalized address or CIDR"
            }
          }
        },
        "required": [
          "id",
          "token",
          "name",
          "scopes",
          "allowed_ips"
        ],
        "additionalProperties": false
      },
      "KeyUpdateRequest": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "name": {
            "type": "string",
            "description": "Key name",
            "minLength": 1,
            "maxLength": 100
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Exact key scope",
              "enum": [
                "read",
                "write"
              ]
            }
          },
          "allowed_ips": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "IPv4/IPv6 address or CIDR"
            }
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "KeyUpdateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "API key UUID",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Key name"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Exact key scope",
              "enum": [
                "read",
                "write"
              ]
            }
          },
          "allowed_ips": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Normalized address or CIDR"
            }
          },
          "enabled": {
            "type": "boolean"
          },
          "disabled_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "revoked_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "name",
          "scopes",
          "allowed_ips",
          "enabled",
          "disabled_at",
          "revoked_at"
        ],
        "additionalProperties": false
      },
      "RevokedResponse": {
        "type": "object",
        "properties": {
          "revoked": {
            "type": "boolean"
          }
        },
        "required": [
          "revoked"
        ],
        "additionalProperties": false
      },
      "TeamGrant": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Grant UUID",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "description": "User UUID",
            "format": "uuid"
          },
          "shop_id": {
            "anyOf": [
              {
                "type": "string",
                "description": "Shop UUID",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "project_id": {
            "anyOf": [
              {
                "type": "string",
                "description": "Legacy alias of shop_id",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "role": {
            "type": "string",
            "description": "Grant role",
            "enum": [
              "owner",
              "developer",
              "viewer"
            ]
          },
          "display_name": {
            "type": "string",
            "description": "User display name"
          },
          "identity": {
            "type": "string",
            "description": "Primary identity label"
          },
          "email": {
            "type": "string",
            "description": "Email label when available"
          },
          "avatar_url": {
            "type": "string",
            "description": "Team avatar URL when available"
          }
        },
        "required": [
          "id",
          "user_id",
          "shop_id",
          "project_id",
          "role",
          "display_name",
          "identity",
          "email",
          "avatar_url"
        ],
        "additionalProperties": false
      },
      "TeamInvite": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Invite UUID",
            "format": "uuid"
          },
          "subject": {
            "type": "string",
            "description": "Invited email or wallet"
          },
          "provider": {
            "type": "string",
            "description": "Identity provider",
            "enum": [
              "email",
              "wallet"
            ]
          },
          "shop_id": {
            "anyOf": [
              {
                "type": "string",
                "description": "Shop UUID",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "project_id": {
            "anyOf": [
              {
                "type": "string",
                "description": "Legacy alias of shop_id",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "role": {
            "type": "string",
            "description": "Invited role",
            "enum": [
              "owner",
              "developer",
              "viewer"
            ]
          },
          "expires_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          },
          "accepted_by": {
            "anyOf": [
              {
                "type": "string",
                "description": "Accepting user UUID",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "revoked_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string",
            "description": "Invite status",
            "enum": [
              "pending",
              "accepted",
              "revoked",
              "expired"
            ]
          },
          "email_sent": {
            "type": "boolean"
          },
          "email_status": {
            "type": "string",
            "description": "Email delivery status"
          },
          "email_sent_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "email_error": {
            "anyOf": [
              {
                "type": "string",
                "description": "Email delivery error"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "subject",
          "provider",
          "shop_id",
          "project_id",
          "role",
          "expires_at",
          "accepted_by",
          "revoked_at",
          "status",
          "email_sent",
          "email_status",
          "email_sent_at",
          "email_error"
        ],
        "additionalProperties": false
      },
      "Team": {
        "type": "object",
        "properties": {
          "grants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TeamGrant"
            }
          },
          "invites": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TeamInvite"
            }
          }
        },
        "required": [
          "grants",
          "invites"
        ],
        "additionalProperties": false
      },
      "InviteRequest": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "description": "Identity provider",
            "enum": [
              "email",
              "wallet"
            ]
          },
          "subject": {
            "type": "string",
            "description": "Email address or wallet address"
          },
          "shop_id": {
            "anyOf": [
              {
                "type": "string",
                "description": "Optional shop scope",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "project_id": {
            "anyOf": [
              {
                "type": "string",
                "description": "Deprecated alias of shop_id",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "role": {
            "type": "string",
            "description": "Grant role",
            "enum": [
              "owner",
              "developer",
              "viewer"
            ]
          }
        },
        "required": [
          "provider",
          "subject",
          "role"
        ],
        "additionalProperties": false
      },
      "InviteDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Invite UUID",
            "format": "uuid"
          },
          "invite_url": {
            "type": "string",
            "description": "Shareable invite URL",
            "format": "uri"
          },
          "status": {
            "type": "string",
            "description": "Invite status"
          },
          "revoked_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "email_sent": {
            "type": "boolean"
          },
          "email_status": {
            "type": "string",
            "description": "Email delivery status"
          },
          "email_sent_at": {
            "anyOf": [
              {
                "type": "string",
                "description": "RFC 3339 timestamp",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ]
          },
          "email_error": {
            "anyOf": [
              {
                "type": "string",
                "description": "Email delivery error"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "invite_url",
          "status",
          "revoked_at",
          "email_sent",
          "email_status",
          "email_sent_at",
          "email_error"
        ],
        "additionalProperties": false
      },
      "InviteAcceptResponse": {
        "type": "object",
        "properties": {
          "merchant_id": {
            "type": "string",
            "description": "Merchant UUID",
            "format": "uuid"
          }
        },
        "required": [
          "merchant_id"
        ],
        "additionalProperties": false
      },
      "InviteRevokeResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Invite UUID",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "const": "revoked"
          },
          "revoked": {
            "type": "boolean"
          },
          "revoked_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "status",
          "revoked",
          "revoked_at"
        ],
        "additionalProperties": false
      },
      "GrantRevokeResponse": {
        "type": "object",
        "properties": {
          "revoked": {
            "type": "boolean"
          }
        },
        "required": [
          "revoked"
        ],
        "additionalProperties": false
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Webhook endpoint UUID",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "description": "HTTPS destination URL",
            "format": "uri"
          },
          "filters": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Event or event group filter"
            }
          },
          "enabled": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "url",
          "filters",
          "enabled"
        ],
        "additionalProperties": false
      },
      "WebhookCreateRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "HTTPS destination URL",
            "format": "uri",
            "maxLength": 2048
          },
          "filters": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Event or event group filter",
              "maxItems": 32
            }
          }
        },
        "required": [
          "url"
        ],
        "additionalProperties": false
      },
      "WebhookCreateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Webhook endpoint UUID",
            "format": "uuid"
          },
          "secret": {
            "type": "string",
            "description": "Signing secret; save it when returned"
          },
          "url": {
            "type": "string",
            "description": "HTTPS destination URL",
            "format": "uri"
          },
          "filters": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Event or event group filter"
            }
          }
        },
        "required": [
          "id",
          "secret",
          "url",
          "filters"
        ],
        "additionalProperties": false
      },
      "WebhookUpdateRequest": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "url": {
            "type": "string",
            "description": "HTTPS destination URL",
            "format": "uri",
            "maxLength": 2048
          },
          "filters": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Event or event group filter",
              "maxItems": 32
            }
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "DeliveryAttempt": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Attempt UUID",
            "format": "uuid"
          },
          "status_code": {
            "type": "integer",
            "description": "HTTP status code, when received"
          },
          "error_code": {
            "type": "string",
            "description": "Delivery error code"
          },
          "created_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "status_code",
          "error_code",
          "created_at"
        ],
        "additionalProperties": false
      },
      "Delivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Delivery UUID",
            "format": "uuid"
          },
          "event_id": {
            "type": "string",
            "description": "Event UUID",
            "format": "uuid"
          },
          "event_kind": {
            "type": "string",
            "description": "Event type"
          },
          "endpoint_id": {
            "type": "string",
            "description": "Webhook endpoint UUID",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "description": "Delivery status",
            "enum": [
              "pending",
              "delivered",
              "failed"
            ]
          },
          "generation": {
            "type": "integer",
            "description": "Delivery generation",
            "minimum": 0
          },
          "created_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          },
          "deadline_at": {
            "type": "string",
            "description": "RFC 3339 timestamp",
            "format": "date-time"
          },
          "attempts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeliveryAttempt"
            }
          }
        },
        "required": [
          "id",
          "event_id",
          "event_kind",
          "endpoint_id",
          "status",
          "generation",
          "created_at",
          "deadline_at",
          "attempts"
        ],
        "additionalProperties": false
      },
      "DeliveryPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Delivery"
            }
          },
          "next_cursor": {
            "type": "string",
            "description": "Opaque cursor; empty string means no next page"
          }
        },
        "required": [
          "items",
          "next_cursor"
        ],
        "additionalProperties": false
      },
      "ReplayResponse": {
        "type": "object",
        "properties": {
          "queued": {
            "type": "boolean"
          }
        },
        "required": [
          "queued"
        ],
        "additionalProperties": false
      },
      "SandboxSimulateRequest": {
        "type": "object",
        "properties": {
          "issuance_id": {
            "type": "string",
            "description": "Sandbox issuance UUID",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "description": "Simulation event kind",
            "enum": [
              "transfer.observed",
              "transfer.confirmed",
              "transfer.reverted",
              "invoice.closed",
              "gas.wait",
              "sweep.failed"
            ]
          },
          "amount": {
            "type": "string",
            "description": "Unsigned integer amount in token base units",
            "pattern": "^[0-9]+$"
          },
          "reference_event_id": {
            "type": "string",
            "description": "Original event ID for transfer.reverted"
          }
        },
        "required": [
          "issuance_id",
          "kind",
          "amount"
        ],
        "additionalProperties": false
      },
      "SandboxAcceptedResponse": {
        "type": "object",
        "properties": {
          "accepted": {
            "type": "boolean"
          }
        },
        "required": [
          "accepted"
        ],
        "additionalProperties": false
      },
      "SandboxOperationResponse": {
        "type": "object",
        "properties": {
          "simulated": {
            "type": "boolean"
          }
        },
        "required": [
          "simulated"
        ],
        "additionalProperties": false
      },
      "SandboxResetResponse": {
        "type": "object",
        "properties": {
          "reset": {
            "type": "boolean"
          }
        },
        "required": [
          "reset"
        ],
        "additionalProperties": false
      }
    }
  }
}
