{
  "openapi": "3.1.0",
  "info": {
    "title": "Kudu Marketplace API",
    "version": "1.0.0",
    "license": {
      "name": "Proprietary — Kudu / Alevia"
    },
    "description": "The REST API white-label partners build their group-buying and escrow front-ends on. It covers authentication & personas, the tenant-scoped catalogue, group-buy (pool) management, the reserve → sign → pay checkout, escrow release & dispute handling, fees, invoicing and relais/delivery.\n\n**Getting started.** This reference is public so you can evaluate the API before you integrate. To build against it you need a **sandbox account**, which we provision on request — [contact us](https://kudu.cash/contact) to have a sandbox tenant and test credentials issued. Production access is then granted to verified businesses via https://kudu.cash/apply.\n\n**Transport & auth.** Send a JSON Web Token as `Authorization: Bearer <jwt>`. Marketplace reads are scoped by the `X-Kudu-Tenant: <slug>` header.\n\n**Response envelope.** Success → `{ \"success\": true, \"data\": <payload> }`. Error → `{ \"success\": false, \"error\": \"<message>\", \"errors\"?: { field: string[] } }`. Paginated payloads put `{ items, pagination }` in `data`.",
    "contact": {
      "name": "Kudu Platform",
      "url": "https://app.kudu.cash"
    }
  },
  "servers": [
    {
      "url": "https://app.kudu.cash",
      "description": "Production"
    },
    {
      "url": "https://sandbox.kudu.cash",
      "description": "Sandbox"
    }
  ],
  "tags": [
    {
      "name": "Auth",
      "description": "Login, whitelabel signup, SSO handoff, persona upgrades, billing mandates."
    },
    {
      "name": "Catalogue",
      "description": "Public, tenant-scoped vendor + group-buy listings and hybrid search."
    },
    {
      "name": "Pool CRUD",
      "description": "Organiser-facing group-buy (SolidarityPool) create / read / update / archive."
    },
    {
      "name": "Reservation",
      "description": "Buyer reserve → sign → pay flow, order dashboard, receipt confirmation."
    },
    {
      "name": "Escrow",
      "description": "Weighted release (organiser cosign + keyless preAuthTx) and settlement."
    },
    {
      "name": "Fees",
      "description": "Phase-5 commission resolver + escrow-deposit quote (whitelabel tenants only)."
    },
    {
      "name": "Invoicing",
      "description": "Factur-X / CII invoices for merchants and buyers."
    },
    {
      "name": "Relais",
      "description": "Carrier point-relais proxy + the partner communal pickup network + delivery webhooks."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/api/auth/login/password": {
      "post": {
        "operationId": "authLoginPassword",
        "tags": [
          "Auth"
        ],
        "summary": "Login with phone-or-email + password",
        "description": "Public. Rate-limited per IP. Returns a 7-day JWT, the device id, and a user summary.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "phone",
                      "password"
                    ],
                    "properties": {
                      "phone": {
                        "type": "string",
                        "minLength": 5,
                        "maxLength": 20
                      },
                      "password": {
                        "type": "string",
                        "minLength": 1
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "email",
                      "password"
                    ],
                    "properties": {
                      "email": {
                        "type": "string",
                        "format": "email"
                      },
                      "password": {
                        "type": "string",
                        "minLength": 1
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AuthTokenResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/auth/register/simple": {
      "post": {
        "operationId": "authRegisterSimple",
        "tags": [
          "Auth"
        ],
        "summary": "Relaxed email+password signup for whitelabel front-ends",
        "description": "Public but gated by the whitelabel toggle (404 when off). Skips the OTP+PIN of the canonical flow. `accountType=BUSINESS` requires `companyName` + a SIRET (FR) or `taxCountry`+ (`taxId` OR `rccm`) (non-FR) for DAC7. `role` is whitelisted to low-privilege the partner roles. Optionally records the FEE mandate at signup. Defaults identity to FR/EUR/Europe-Paris; `signupSource` is set from `X-Kudu-Tenant` (default `your-tenant`).\n",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleRegisterInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Account created + session issued.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AuthTokenResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundWhenGated"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/auth/forgot-password": {
      "post": {
        "operationId": "authForgotPassword",
        "tags": [
          "Auth"
        ],
        "summary": "Request a password-reset link",
        "description": "Public, whitelabel-gated. Always 200 (no user enumeration). Issues a stateless 30-min reset JWT (a scoped reset claim) emailed to the user; in non-prod the token is echoed.\n",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generic acknowledgement.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "message": {
                              "type": "string"
                            },
                            "resetToken": {
                              "type": "string",
                              "description": "dev-only"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundWhenGated"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/auth/reset-password": {
      "post": {
        "operationId": "authResetPassword",
        "tags": [
          "Auth"
        ],
        "summary": "Reset password with a signed token",
        "description": "Public, whitelabel-gated. Verifies the `password-reset` JWT, updates the password, and terminates all active sessions.\n",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token",
                  "password"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string",
                    "minLength": 8
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password reset.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "message": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/auth/me": {
      "get": {
        "operationId": "authMe",
        "tags": [
          "Auth"
        ],
        "summary": "Current user, wallet, spending and agent context",
        "description": "Bearer. Rich profile used to bootstrap the front-end (region, wallet, verification, agent).",
        "responses": {
          "200": {
            "description": "Current user context.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AuthMeResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/auth/logout": {
      "post": {
        "operationId": "authLogout",
        "tags": [
          "Auth"
        ],
        "summary": "Terminate the current session",
        "description": "Bearer-optional. Idempotent — always 200, even with no/invalid session.",
        "security": [
          {
            "bearerAuth": []
          },
          {}
        ],
        "responses": {
          "200": {
            "description": "Logged out.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "message": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/sso/handoff": {
      "post": {
        "operationId": "authSsoHandoff",
        "tags": [
          "Auth"
        ],
        "summary": "Exchange a Bearer token for a one-time SSO code (step 1 of 2)",
        "description": "Bearer, whitelabel-gated. Returns a short-lived (2-min) single-purpose `the partner-sso` JWT. The front-end then TOP-LEVEL-NAVIGATES (not XHR) to `GET /api/auth/sso/start?code=…`. See the integration guide SSO handoff.\n",
        "responses": {
          "200": {
            "description": "One-time handoff code.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "description": "2-min the partner-sso JWT"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundWhenGated"
          }
        }
      }
    },
    "/api/auth/sso/start": {
      "get": {
        "operationId": "authSsoStart",
        "tags": [
          "Auth"
        ],
        "summary": "Consume SSO code, mint first-party cookie, redirect (step 2 of 2)",
        "description": "Public, whitelabel-gated. **This is a browser navigation target, not an XHR endpoint.** Verifies the handoff code, mints a fresh `kudu_session` cookie (SameSite=None;Secure when loaded in an iframe), and **307-redirects** into Kudu onboarding or back to `returnTo`. `returnTo` must be in the the approved-origins allowlist allowlist; `dest` must be an internal path.\n",
        "security": [],
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "returnTo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Allowlisted front-end origin URL."
          },
          {
            "name": "dest",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Internal Kudu path to land on."
          }
        ],
        "responses": {
          "307": {
            "description": "Redirect into Kudu onboarding or back to the front-end. Sets `kudu_session` cookie.",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                }
              },
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFoundWhenGated"
          }
        }
      }
    },
    "/api/me/become-seller": {
      "post": {
        "operationId": "meBecomeSeller",
        "tags": [
          "Auth"
        ],
        "summary": "Upgrade CONSUMER → BUSINESS",
        "description": "Bearer, whitelabel-gated. Idempotent (returns `alreadyBusiness` if already BUSINESS). Captures business identity for DAC7 (companyName + SIRET/foreign tax id). Role unchanged.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "companyName"
                ],
                "properties": {
                  "companyName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "siret": {
                    "type": "string",
                    "pattern": "^\\d{14}$"
                  },
                  "taxCountry": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2
                  },
                  "taxId": {
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 40
                  },
                  "acceptFeeMandate": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upgraded (or already a business).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "accountType": {
                              "type": "string",
                              "enum": [
                                "BUSINESS"
                              ]
                            },
                            "role": {
                              "type": "string"
                            },
                            "alreadyBusiness": {
                              "type": "boolean"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundWhenGated"
          }
        }
      }
    },
    "/api/me/become-organiser/prepare": {
      "post": {
        "operationId": "meBecomeOrganiserPrepare",
        "tags": [
          "Auth"
        ],
        "summary": "Prepare the 1-EURC buyer-as-organiser activation (step 1 of 2)",
        "description": "Bearer, whitelabel-gated. Pure buyers (CONSUMER + role `user`) unlock the `organiser` role by signing a one-time 1 EURC platform fee non-custodially. Returns an unsigned Stellar payment XDR + a grant id. Returns `alreadyOrganiser` for users who already qualify. Requires a registered Stellar account. Rate-limited.\n",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nonce": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Activation prepared (or already an organiser).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "oneOf": [
                            {
                              "type": "object",
                              "properties": {
                                "alreadyOrganiser": {
                                  "type": "boolean",
                                  "enum": [
                                    true
                                  ]
                                }
                              }
                            },
                            {
                              "$ref": "#/components/schemas/OrganiserGrantPrepareResult"
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundWhenGated"
          }
        }
      }
    },
    "/api/me/become-organiser/submit": {
      "post": {
        "operationId": "meBecomeOrganiserSubmit",
        "tags": [
          "Auth"
        ],
        "summary": "Confirm the 1-EURC payment and grant the organiser role (step 2 of 2)",
        "description": "Bearer, whitelabel-gated. Primary path — client cosigns + submits the XDR and passes the `txHash`; fallback — client passes `signedXdr` for the server to submit. Verifies on Horizon, atomically settles the grant and grants the role. Returns `pending` during indexing lag. Rate-limited.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "grantId"
                ],
                "properties": {
                  "grantId": {
                    "type": "string"
                  },
                  "txHash": {
                    "type": "string"
                  },
                  "signedXdr": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Settled, or pending indexing.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "settled": {
                              "type": "boolean"
                            },
                            "role": {
                              "type": "string"
                            },
                            "idempotent": {
                              "type": "boolean"
                            },
                            "pending": {
                              "type": "boolean"
                            },
                            "reason": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundWhenGated"
          }
        }
      }
    },
    "/api/me/become-organiser/{grantId}": {
      "get": {
        "operationId": "meBecomeOrganiserStatus",
        "tags": [
          "Auth"
        ],
        "summary": "Organiser-grant status (+ fresh XDR)",
        "description": "Bearer, whitelabel-gated, owner-only (404 on mismatch). Rebuilds a fresh unsigned XDR on every call while `AWAITING_SIGNATURE` (Stellar sequence numbers expire).\n",
        "parameters": [
          {
            "name": "grantId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Grant status.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/OrganiserGrant"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/mandates": {
      "get": {
        "operationId": "listMandates",
        "tags": [
          "Auth"
        ],
        "summary": "Caller's billing mandates + current mandate texts",
        "description": "Bearer. Returns accepted/revoked mandates and the server-authoritative text per kind.",
        "responses": {
          "200": {
            "description": "Mandates + texts.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "mandates": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/Mandate"
                              }
                            },
                            "texts": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "kind": {
                                    "$ref": "#/components/schemas/MandateKind"
                                  },
                                  "text": {
                                    "type": "string"
                                  },
                                  "hash": {
                                    "type": "string"
                                  },
                                  "version": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "operationId": "acceptMandate",
        "tags": [
          "Auth"
        ],
        "summary": "Accept a billing mandate (FEE | COMMISSION | RELAIS)",
        "description": "Bearer. Records server-authoritative text+version+hash and the accepting IP (CGI art. 289 I-2).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "$ref": "#/components/schemas/MandateKind"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Mandate recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/Mandate"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/tenant/merchants": {
      "get": {
        "operationId": "tenantMerchants",
        "tags": [
          "Catalogue"
        ],
        "summary": "Public vendor list (tenant-scoped)",
        "description": "Public, rate-limited (120/min/IP). ACTIVE merchants only; includes the `storefrontLinks` blob.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/QParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated merchants.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/PaginatedData"
                            },
                            {
                              "properties": {
                                "items": {
                                  "type": "array",
                                  "items": {
                                    "$ref": "#/components/schemas/MerchantCard"
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/tenant/group-buys": {
      "get": {
        "operationId": "tenantGroupBuys",
        "tags": [
          "Catalogue"
        ],
        "summary": "Public group-buy list (tenant-scoped)",
        "description": "Public, rate-limited (120/min/IP). GROUPS pools with `marketplaceVisibility` LISTED|FEATURED, not archived. Returns the redacted `config` (seller phone / notes / links / escrow keys removed), `units[]`, `pickupPoints[]`, member names.\n",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          },
          {
            "$ref": "#/components/parameters/QParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated group-buys.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/PaginatedData"
                            },
                            {
                              "properties": {
                                "items": {
                                  "type": "array",
                                  "items": {
                                    "$ref": "#/components/schemas/GroupBuyCard"
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/tenant/search": {
      "get": {
        "operationId": "tenantSearch",
        "tags": [
          "Catalogue"
        ],
        "summary": "Hybrid catalogue search (+ popular shelf)",
        "description": "Public, rate-limited (300/min/IP — search-as-you-type). Trigram + pgvector (e5 384-d) + structured scoring. `q` under 2 chars returns the popular shelf only.\n",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 8
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "merchants",
                "pools"
              ],
              "default": "all"
            }
          },
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "lng",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "postal_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "radius",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 500
            },
            "description": "km"
          }
        ],
        "responses": {
          "200": {
            "description": "Search results.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/SearchResponse"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/tenant/pilot-requests": {
      "post": {
        "operationId": "tenantPilotRequest",
        "tags": [
          "Catalogue"
        ],
        "summary": "Whitelabel lead capture",
        "description": "Public, whitelabel-gated. Captures a pilot-space lead + first-touch UTM attribution.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PilotRequestInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Lead recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "message": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundWhenGated"
          }
        }
      }
    },
    "/api/merchant/pools": {
      "get": {
        "operationId": "merchantPoolsList",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "The signed-in organiser's own pools",
        "description": "Bearer (authenticated). Lists ONLY the caller's own pools (organiserId), tenant-scoped, any status/visibility — a non-organiser simply gets an empty list.",
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/PoolType"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/PoolStatus"
            }
          },
          {
            "name": "archived",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated owned pools.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/PaginatedData"
                            },
                            {
                              "properties": {
                                "items": {
                                  "type": "array",
                                  "items": {
                                    "$ref": "#/components/schemas/GroupBuy"
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      },
      "post": {
        "operationId": "merchantPoolsCreate",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Create a group-buy as organiser",
        "description": "Bearer + `canOrganise` (403 otherwise). Uses `merchantPoolCreateSchema` (= public schema + `sellerIdentifier`/`sellerMerchantSlug`, resolved to `sellerId` at the route). Gates `organiserCommissionPercent` to BUSINESS accounts. Records the COMMISSION mandate when `acceptCommissionMandate` is set on a brokered paid pool. Reuses the same `createPool` engine as `POST /api/pools`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MerchantPoolCreateInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pool created.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GroupBuy"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/merchant/pools/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "$ref": "#/components/parameters/XKuduTenant"
        }
      ],
      "get": {
        "operationId": "merchantPoolGet",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "One owned pool (full detail for edit hydration)",
        "description": "Bearer + owner. 404 if missing, another tenant, or another owner. Secrets stripped.",
        "responses": {
          "200": {
            "description": "Pool detail.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GroupBuy"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "patch": {
        "operationId": "merchantPoolUpdate",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Update an owned pool (draft-only for money-spine)",
        "description": "Bearer + owner. Money-spine edits (seller/payout/commission/relais) are DRAFT-only; `marketplaceVisibility` (PRIVATE only here) + `country` editable post-publish. Re-syncs PoolPickupPoint rows for GROUPS `config.relais`. Shares the schema with `PATCH /api/pools/{id}`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MerchantPoolUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pool updated.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GroupBuy"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/pools": {
      "get": {
        "operationId": "poolsList",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Buyer-facing pool list (owned + joined)",
        "description": "Bearer. Mixes pools the user organises and has joined. Mirror of `/merchant/pools` GET but a wider WHERE.",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/PoolType"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/PoolStatus"
            }
          },
          {
            "name": "archived",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated pools.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/PaginatedData"
                            },
                            {
                              "properties": {
                                "items": {
                                  "type": "array",
                                  "items": {
                                    "$ref": "#/components/schemas/GroupBuy"
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "operationId": "poolsCreate",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Create a pool (public/buyer path)",
        "description": "Bearer + `canOrganise`. Same `createPool` engine + `poolCreateSchema` as the merchant path (post seller-resolution).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PoolCreateInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pool created.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GroupBuy"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/pools/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "$ref": "#/components/parameters/XKuduTenant"
        }
      ],
      "get": {
        "operationId": "poolGet",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "One pool (public for published group-buys)",
        "description": "Bearer-optional. Published GROUPS (status ≠ DRAFT, not archived) and LISTED/FEATURED FUNDING are publicly readable; anonymous viewers get members/myReservations empty and sensitive data hidden. Lazy-sweeps expired PENDING reservations; reclaim XDRs redacted.\n",
        "security": [
          {
            "bearerAuth": []
          },
          {}
        ],
        "responses": {
          "200": {
            "description": "Pool detail.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/GroupBuy"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "patch": {
        "operationId": "poolUpdate",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Update a pool (owner, draft-only)",
        "description": "Bearer + organiser. Draft-only except `marketplaceVisibility` (PRIVATE) + `country`. Rejects setting LISTED here (use the paid `/pools/{id}/list`). On eligible delist refunds the listing fee. Shares the schema with `PATCH /api/merchant/pools/{id}`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PoolUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pool updated.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/GroupBuy"
                            },
                            {
                              "properties": {
                                "refund": {
                                  "type": [
                                    "object",
                                    "null"
                                  ],
                                  "properties": {
                                    "amount": {
                                      "type": "string"
                                    },
                                    "source": {
                                      "type": "string"
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/pools/{id}/archive": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "poolArchive",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Soft-archive a pool",
        "description": "Bearer + organiser. Sets archivedAt; 400 if already archived. Audit-logged.",
        "responses": {
          "200": {
            "description": "Archived.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "archivedAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "delete": {
        "operationId": "poolUnarchive",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Restore an archived pool",
        "description": "Bearer + organiser. Clears archivedAt; 400 if not archived. Audit-logged.",
        "responses": {
          "200": {
            "description": "Restored.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "archivedAt": {
                              "type": "null"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/merchant/profile": {
      "get": {
        "operationId": "merchantProfileGet",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "The authenticated merchant's profile",
        "description": "Bearer + `requireMerchant` (403 without an active MerchantProfile).",
        "responses": {
          "200": {
            "description": "Merchant profile.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/MerchantProfile"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      },
      "patch": {
        "operationId": "merchantProfileUpdate",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Update the merchant's profile fiche",
        "description": "Bearer + `requireMerchant`. All fields optional. `escrowWindowHours` capped at 168 (7 days).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MerchantProfileUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Profile updated.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/MerchantProfile"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/pools/{id}/units/{unitId}/reserve-preflight": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "unitId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "$ref": "#/components/parameters/XKuduTenant"
        }
      ],
      "get": {
        "operationId": "reservePreflight",
        "tags": [
          "Reservation"
        ],
        "summary": "No-side-effect reserve gate",
        "description": "Bearer. Validates pool/unit/stock, the buyer's Stellar account+trustline+balance (via Horizon), the per-buyer reservation cap, and the pool's max-order cap — without revealing the exact balance gap.\n",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100000
            },
            "description": "quantity"
          }
        ],
        "responses": {
          "200": {
            "description": "Preflight result.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ReservePreflightResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/pools/{id}/units/{unitId}/reserve/prepare": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "unitId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "$ref": "#/components/parameters/XKuduTenant"
        }
      ],
      "post": {
        "operationId": "reservePrepare",
        "tags": [
          "Reservation"
        ],
        "summary": "Reserve step 1/3 — hold stock, return half-signed CB-create XDR",
        "description": "Bearer (tenant-gated). Atomically holds stock, creates a PENDING reservation (5-min TTL), and builds a treasury half-signed claimable-balance-create XDR for the buyer to co-sign client-side. Idempotent on `nonce`. The buyer's key never leaves the client.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReservePrepareInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reservation prepared.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ReservePrepareResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        }
      }
    },
    "/api/pools/{id}/units/{unitId}/reserve/submit": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "unitId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "$ref": "#/components/parameters/XKuduTenant"
        }
      ],
      "post": {
        "operationId": "reserveSubmit",
        "tags": [
          "Reservation"
        ],
        "summary": "Reserve step 2/3 — submit signed CB-create, get reclaim XDR",
        "description": "Bearer. Submits the buyer-signed CB-create XDR to Horizon, extracts the `balanceId`, and returns an unsigned reclaim envelope. On Horizon failure rolls back stock and CANCELs. Reservation stays PENDING until `submit-reclaim`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reservationId",
                  "signedCreateXdr"
                ],
                "properties": {
                  "reservationId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "signedCreateXdr": {
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 200000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Submitted; reclaim envelope returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ReserveSubmitResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/pools/{id}/units/{unitId}/reserve/submit-reclaim": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "unitId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "$ref": "#/components/parameters/XKuduTenant"
        }
      ],
      "post": {
        "operationId": "reserveSubmitReclaim",
        "tags": [
          "Reservation"
        ],
        "summary": "Reserve step 3/3 — store reclaim, mark PAID",
        "description": "Bearer. Validates the signed reclaim envelope (balanceId match + claimClaimableBalance op), persists it, transitions PENDING → PAID, and writes the contribution ledger entries. The reclaim XDR is stored (not submitted) for a fee-bumped refund relay if the pool dissolves.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reservationId",
                  "signedReclaimXdr"
                ],
                "properties": {
                  "reservationId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "signedReclaimXdr": {
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 200000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reservation PAID.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "reservationId": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "PAID"
                              ]
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/pools/{id}/reservations": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "poolReservationsList",
        "tags": [
          "Reservation"
        ],
        "summary": "Organiser list of a pool's reservations",
        "description": "Bearer + organiser. GROUPS only. Reclaim XDR always redacted. Used by container-intake UI.",
        "responses": {
          "200": {
            "description": "Reservations.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Reservation"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/pools/{id}/reservations/{reservationId}/confirm-receipt": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "reservationId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "reservationConfirmReceipt",
        "tags": [
          "Reservation"
        ],
        "summary": "Buyer confirms receipt (authoritative — arms keyless release)",
        "description": "Bearer + buyer. **The authoritative the partner-P3 delivery signal.** Sets `receiptConfirmedAt` + `deliverySource=BUYER_SCAN`, which arms the keyless on-chain release and starts the T+48h timer. Requires reservation PAID|INTAKE_RECEIVED and pool ACTIVE. Idempotent. Distinct from `confirm-delivery`.\n",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "receiptProof": {
                    "type": "string",
                    "maxLength": 20000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Receipt confirmed.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "receiptConfirmedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "alreadyConfirmed": {
                              "type": "boolean"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/pools/{id}/reservations/{reservationId}/confirm-delivery": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "reservationId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "reservationConfirmDelivery",
        "tags": [
          "Reservation"
        ],
        "summary": "Buyer confirms delivery (legacy off-chain marker)",
        "description": "Bearer + buyer. **Legacy** off-chain confirmation post-release (not the authoritative receipt signal — use `confirm-receipt`). Marks DELIVERED, increments member.unitsReceived, and auto-completes the pool when all reservations are DELIVERED/REFUNDED. Requires reservation PAID|INTAKE_RECEIVED and pool RELEASING.\n",
        "responses": {
          "200": {
            "description": "Delivery confirmed.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "DELIVERED"
                              ]
                            },
                            "poolCompleted": {
                              "type": "boolean"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/pools/{id}/reservations/{reservationId}/ship": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "reservationId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "reservationShip",
        "tags": [
          "Reservation"
        ],
        "summary": "Organiser marks a reservation shipped",
        "description": "Bearer + organiser. Records shippedAt + trackingRef + deliveryProvider (matched later by a carrier POD webhook). `assertFulfilled=true` records a SELLER_ASSERT delivery signal for in-person/untracked delivery, opening a dispute grace window.\n",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "trackingRef": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "deliveryProvider": {
                    "type": "string",
                    "maxLength": 64
                  },
                  "assertFulfilled": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Marked shipped.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "shipped": {
                              "type": "boolean"
                            },
                            "trackingRef": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "assertedFulfilled": {
                              "type": "boolean"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/tenant/my-orders": {
      "get": {
        "operationId": "tenantMyOrders",
        "tags": [
          "Reservation"
        ],
        "summary": "Buyer's group-buy order dashboard (tenant-scoped)",
        "description": "Bearer. Tenant-scoped order list with computed escrow display. Signing material (createXdr/reclaimXdr) is never exposed. NOTE - returns an ad-hoc `data` shape (`{items,total,hasMore,page,limit}`), not the standard pagination envelope.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Orders.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "items": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/Order"
                              }
                            },
                            "total": {
                              "type": "integer"
                            },
                            "hasMore": {
                              "type": "boolean"
                            },
                            "page": {
                              "type": "integer"
                            },
                            "limit": {
                              "type": "integer"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/user/pending-reservations": {
      "get": {
        "operationId": "userPendingReservations",
        "tags": [
          "Reservation"
        ],
        "summary": "Buyer's \"payments to approve\" inbox",
        "description": "Bearer. The caller's own PENDING, non-expired reservations across all pools (with the half-signed createXdr to sign) — lets a phone pick up a reservation prepared on a PC.\n",
        "responses": {
          "200": {
            "description": "Pending reservations.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "reservations": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/PendingReservation"
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/user/stellar-balances": {
      "get": {
        "operationId": "userStellarBalances",
        "tags": [
          "Reservation"
        ],
        "summary": "Live on-chain Stellar balance snapshot",
        "description": "Bearer. Live Horizon query; null if no Stellar account; empty balances if not ACTIVE; 502 if Horizon is unreachable.",
        "responses": {
          "200": {
            "description": "Balances.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "stellar": {
                              "type": [
                                "object",
                                "null"
                              ],
                              "properties": {
                                "publicKey": {
                                  "type": "string"
                                },
                                "status": {
                                  "type": "string"
                                },
                                "onChain": {
                                  "type": "boolean"
                                },
                                "balances": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "assetCode": {
                                        "type": "string"
                                      },
                                      "assetIssuer": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "balance": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          }
        }
      }
    },
    "/api/pools/{id}/confirm-order/prepare": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "confirmOrderPrepare",
        "tags": [
          "Escrow"
        ],
        "summary": "Build the batched weighted-release XDRs (organiser cosign)",
        "description": "Bearer + organiser. Builds mediator-signed, organiser-cosign-required batched release XDRs (a fixed batch size). Enforces the receipt-confirmed gate, dispute-grace window, and intake checks. Returns the weighted split (SELLER principal + ORGANISER commission + PLATFORM fee + optional RELAIS leg). The session is stored in server-side session state.\n",
        "responses": {
          "200": {
            "description": "Release prepared.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ConfirmOrderPrepareResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/pools/{id}/confirm-order/submit": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "confirmOrderSubmit",
        "tags": [
          "Escrow"
        ],
        "summary": "Submit the cosigned release; write payout ledger + invoices",
        "description": "Bearer + organiser. Submits the release fee-bumps to Horizon, transitions the pool to RELEASING, writes PAYOUT ledger entries (SELLER/ORGANISER/RELAIS/PLATFORM), records the commission split, and generates release invoices (sessionId-keyed). On partial failure stores recovery metadata for admin.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sessionId",
                  "signedXdrs"
                ],
                "properties": {
                  "sessionId": {
                    "type": "string"
                  },
                  "signedXdrs": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 100,
                    "items": {
                      "type": "string",
                      "minLength": 10,
                      "maxLength": 200000
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Released.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "RELEASING"
                              ]
                            },
                            "txHashes": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "shape": {
                              "type": "string"
                            },
                            "sellerPrincipal": {
                              "type": "string"
                            },
                            "organiserCommission": {
                              "type": "string"
                            },
                            "relaisCommission": {
                              "type": "string"
                            },
                            "platformFee": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/pools/{id}/confirm-order/arm-keyless/prepare": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "armKeylessPrepare",
        "tags": [
          "Escrow"
        ],
        "summary": "Pre-build the keyless (preAuthTx) weighted release",
        "description": "Bearer + organiser. Pre-builds the keyless release R, hashes it (preAuthTx), and arms it via a sponsor-sourced (immediate) or recipient-sourced (deferred) tx. `minTimeUnix` = receiptConfirmedAt + 48h; after it, anyone can submit R with no Kudu signature. Single-tx (op-count limited); larger pools use the confirm-order accelerator.\n",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "deferred": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Arming prepared.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ArmKeylessPrepareResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/pools/{id}/confirm-order/arm-keyless/submit": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "armKeylessSubmit",
        "tags": [
          "Escrow"
        ],
        "summary": "Submit the cosigned arming transaction",
        "description": "Bearer + organiser. Immediate — submits now, schedules a keyless-release relay fallback. Deferred — stores the organiser-signed arm envelope + schedules a release-eligibility job to submit at grace-end only if no dispute is open (Kudu never arbitrates).\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sessionId",
                  "signedArmXdr"
                ],
                "properties": {
                  "sessionId": {
                    "type": "string"
                  },
                  "signedArmXdr": {
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 200000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Armed (immediate) or scheduled (deferred).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "armed": {
                              "type": "boolean"
                            },
                            "scheduled": {
                              "type": "boolean"
                            },
                            "deferred": {
                              "type": "boolean"
                            },
                            "armTxHash": {
                              "type": "string"
                            },
                            "eligibleAtUnix": {
                              "type": "integer"
                            },
                            "minTimeUnix": {
                              "type": "integer"
                            },
                            "shape": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/merchant/pools/{id}/deposit": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "$ref": "#/components/parameters/XKuduTenant"
        }
      ],
      "post": {
        "operationId": "merchantPoolDepositCreate",
        "tags": [
          "Escrow"
        ],
        "summary": "Create the merchant escrow deposit (bonne-foi)",
        "description": "Bearer + `requireMerchant`, whitelabel-gated, owner+tenant-gated. Creates an `EscrowDeposit` (status HELD), quoting cost from the merchant's active fee schedule. Returns a `signatureHandoff` placeholder (not yet on-chain). 409 on re-funding.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amountEurCents",
                  "escrowRule",
                  "participants",
                  "pickupPoints"
                ],
                "properties": {
                  "amountEurCents": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "escrowRule": {
                    "$ref": "#/components/schemas/EscrowRule"
                  },
                  "participants": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "pickupPoints": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "maxPoolMembers": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Deposit created.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/EscrowDeposit"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "get": {
        "operationId": "merchantPoolDepositGet",
        "tags": [
          "Escrow"
        ],
        "summary": "Poll the escrow deposit state",
        "description": "Bearer + `requireMerchant`, whitelabel-gated, owner+tenant-gated. Returns live status + remaining cents.",
        "responses": {
          "200": {
            "description": "Deposit state.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/EscrowDeposit"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/fees/resolve": {
      "post": {
        "operationId": "feesResolve",
        "tags": [
          "Fees"
        ],
        "summary": "Resolve the effective commission for an order",
        "description": "Public, tenant-scoped. Drives the partner's /tarifs calculator and the pool-create commission line. **Whitelabel-only**: returns 404 for the default `kudu` tenant (the Phase-5 engine is whitelabel-tenant-only). When `merchantSlug` is given, the merchant's fee overrides are deep-merged onto the tenant schedule.\n",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FeeResolveInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resolved fee.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/FeeResolved"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/fees/quote-deposit": {
      "post": {
        "operationId": "feesQuoteDeposit",
        "tags": [
          "Fees"
        ],
        "summary": "Quote the escrow + bonne-foi deposit",
        "description": "Public, tenant-scoped. Estimates on-chain escrow cost + the refundable bonne-foi deposit a merchant pre-funds. **Whitelabel-only**: 404 for the default `kudu` tenant.\n",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "escrowRule",
                  "participants",
                  "pickupPoints"
                ],
                "properties": {
                  "escrowRule": {
                    "$ref": "#/components/schemas/EscrowRule"
                  },
                  "participants": {
                    "type": "integer"
                  },
                  "pickupPoints": {
                    "type": "integer"
                  },
                  "maxPoolMembers": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deposit quote.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/EscrowQuoteResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/merchant/invoices": {
      "get": {
        "operationId": "merchantInvoices",
        "tags": [
          "Invoicing"
        ],
        "summary": "The seller/organiser's invoices (issuer or recipient)",
        "description": "Bearer. Paginated; optional `kind` filter. Heavy Factur-X XML omitted — fetch per-invoice.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/InvoiceKind"
            }
          },
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated invoices.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/PaginatedData"
                            },
                            {
                              "properties": {
                                "items": {
                                  "type": "array",
                                  "items": {
                                    "$ref": "#/components/schemas/Invoice"
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/merchant/invoices/{id}/facturx": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "merchantInvoiceFacturX",
        "tags": [
          "Invoicing"
        ],
        "summary": "Factur-X / CII XML for one invoice",
        "description": "Bearer, issuer-or-recipient only. Returns the EN16931 / Factur-X BASIC CII XML — wrapped in the JSON envelope as `{ number, filename, contentType, xml }` (not a raw XML body).\n",
        "responses": {
          "200": {
            "description": "Factur-X document.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/FacturXResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/user/invoices": {
      "get": {
        "operationId": "userInvoices",
        "tags": [
          "Invoicing"
        ],
        "summary": "The buyer's GOODS invoices",
        "description": "Bearer. GOODS invoices where the user is the recipient. No `kind` filter.",
        "parameters": [
          {
            "$ref": "#/components/parameters/PageParam"
          },
          {
            "$ref": "#/components/parameters/LimitParam"
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated buyer invoices.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/PaginatedData"
                            },
                            {
                              "properties": {
                                "items": {
                                  "type": "array",
                                  "items": {
                                    "$ref": "#/components/schemas/Invoice"
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/relais/service-points": {
      "get": {
        "operationId": "relaisServicePoints",
        "tags": [
          "Relais"
        ],
        "summary": "Carrier point-relais lookup (Sendcloud proxy)",
        "description": "Public, rate-limited (60/min/IP). Proxies Sendcloud (secret stays server-side), fanning out across configured carriers. NOTE - returns an ad-hoc `data` shape (`{points,count}`). 503 if Sendcloud is not configured.\n",
        "security": [],
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "FR"
            }
          },
          {
            "name": "postal_code",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "postal_code OR lat+lng required"
          },
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "lng",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "radius",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 5000
            },
            "description": "metres"
          },
          {
            "name": "carriers",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "comma-separated carrier slugs"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Service points.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "points": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/ServicePoint"
                              }
                            },
                            "count": {
                              "type": "integer"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/api/relais/shared": {
      "get": {
        "operationId": "relaisShared",
        "tags": [
          "Relais"
        ],
        "summary": "the partner communal pickup network (tenant-scoped)",
        "description": "Public, rate-limited. ACTIVE RelaisOperators for the tenant. NOTE - ad-hoc `data` shape (`{items,count}`).\n",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          },
          {
            "name": "region",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dept",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Communal relais.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "items": {
                              "type": "array",
                              "items": {
                                "$ref": "#/components/schemas/RelaisOperator"
                              }
                            },
                            "count": {
                              "type": "integer"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/relais/{slug}": {
      "parameters": [
        {
          "name": "slug",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "$ref": "#/components/parameters/XKuduTenant"
        }
      ],
      "get": {
        "operationId": "relaisProfile",
        "tags": [
          "Relais"
        ],
        "summary": "Public profile for one communal relais operator",
        "description": "Public, rate-limited. 404 if not ACTIVE or another tenant. Includes up to 24 converging pools.",
        "security": [],
        "responses": {
          "200": {
            "description": "Relais profile + converging pools.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/RelaisOperator"
                            },
                            {
                              "properties": {
                                "pools": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "id": {
                                        "type": "string"
                                      },
                                      "ref": {
                                        "type": "string"
                                      },
                                      "name": {
                                        "type": "string"
                                      },
                                      "status": {
                                        "$ref": "#/components/schemas/PoolStatus"
                                      },
                                      "unitPrice": {
                                        "type": "string"
                                      },
                                      "deadline": {
                                        "type": [
                                          "string",
                                          "null"
                                        ],
                                        "format": "date-time"
                                      },
                                      "memberCount": {
                                        "type": "integer"
                                      },
                                      "maxMembers": {
                                        "type": [
                                          "integer",
                                          "null"
                                        ]
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/relais/apply": {
      "post": {
        "operationId": "relaisApply",
        "tags": [
          "Relais"
        ],
        "summary": "Apply to join the communal pickup network",
        "description": "Public-or-Bearer, whitelabel-gated, rate-limited (10/hour/IP). Creates a PENDING RelaisOperator; an admin verifies it via an internal review step. If signed in, the applicant's userId is linked.\n",
        "security": [
          {
            "bearerAuth": []
          },
          {}
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/XKuduTenant"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RelaisApplyInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Application created (PENDING).",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "slug": {
                              "type": "string"
                            },
                            "status": {
                              "$ref": "#/components/schemas/RelaisOperatorStatus"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundWhenGated"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/webhooks/delivery/{provider}": {
      "parameters": [
        {
          "name": "provider",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "enum": [
              "sendcloud",
              "inhouse",
              "mondial_relay",
              "colissimo"
            ]
          }
        }
      ],
      "post": {
        "operationId": "deliveryWebhook",
        "tags": [
          "Relais"
        ],
        "summary": "Carrier / first-party proof-of-delivery webhook",
        "description": "Webhook secret per provider (HMAC-SHA256 or shared-secret). Normalises each provider payload to a canonical delivery event, matches a reservation by reservationId or trackingRef, and on a delivered event sets `receiptConfirmedAt` (same arming effect as a buyer scan). Idempotent. Always returns 200 so carriers don't retry; 401 on signature failure.\n",
        "security": [
          {
            "webhookSignature": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Provider-specific payload (normalised server-side).",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "received": {
                      "type": "boolean"
                    },
                    "delivered": {
                      "type": "boolean"
                    },
                    "duplicate": {
                      "type": "boolean"
                    },
                    "recorded": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/pools/{id}/publish": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "poolPublishPrepare",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Publish step 1/2 — build the on-chain provisioning XDR",
        "description": "Bearer + organiser. GROUPS only. Builds a treasury+recipient half-signed Stellar provisioning transaction and records the creation fee; the pool stays DRAFT until the PUT. A freshly created pool is DRAFT and NOT reservable — publish moves it to FORMING.\n",
        "responses": {
          "200": {
            "description": "Provisioning XDR prepared.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PublishPrepareResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "put": {
        "operationId": "poolPublishSubmit",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Publish step 2/2 — submit signed provisioning tx (DRAFT → FORMING)",
        "description": "Bearer + organiser. Submits the fully-signed XDR to Horizon, verifies the on-chain escrow, transitions the pool DRAFT → FORMING (now open to buyers), and schedules the order-deadline job. Listing on the marketplace is a separate step (`POST /pools/{id}/list`).\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "signedXdr"
                ],
                "properties": {
                  "signedXdr": {
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 200000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Published; pool is FORMING.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "FORMING"
                              ]
                            },
                            "publishTxHash": {
                              "type": "string"
                            },
                            "recipientPublicKey": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/pools/{id}/list": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "poolList",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Paid marketplace listing (PRIVATE → LISTED)",
        "description": "Bearer + organiser. Charges the listing fee (default 2 EURC, tunable per pool type) and flips marketplaceVisibility PRIVATE → LISTED so buyers can discover it. Requires the pool FORMING/ACTIVE, organiser KYC approved, and sufficient EURC balance. Rejected for CONTRACT pools. (To delist, PATCH marketplaceVisibility back to PRIVATE.)\n",
        "responses": {
          "200": {
            "description": "Listed.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "pool": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "marketplaceVisibility": {
                                  "type": "string",
                                  "enum": [
                                    "LISTED"
                                  ]
                                }
                              }
                            },
                            "charged": {
                              "type": "object",
                              "properties": {
                                "amount": {
                                  "type": "number"
                                },
                                "currency": {
                                  "type": "string",
                                  "enum": [
                                    "EURC"
                                  ]
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/pools/{id}/members": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "poolMembers",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Pool roster",
        "description": "Bearer (member or organiser). Returns the pool's members.",
        "responses": {
          "200": {
            "description": "Members.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/PoolMember"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/pools/{id}/units": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "poolUnitsList",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "List catalogue line items",
        "description": "Bearer. The pool's purchasable units (created inline at pool-create or via POST here).",
        "responses": {
          "200": {
            "description": "Units.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/PoolUnit"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "post": {
        "operationId": "poolUnitCreate",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Add a catalogue line item",
        "description": "Bearer + organiser. GROUPS only; pool must be DRAFT or FORMING.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UnitCreateInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Unit created.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PoolUnit"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/pools/{id}/units/{unitId}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "unitId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "poolUnitUpdate",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Edit a catalogue line item",
        "description": "Bearer + organiser. GROUPS only; pool DRAFT/FORMING and the unit must have zero reservations. On FORMING a capacity failsafe blocks dropping price/units below config.minimumOrderAmount.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UnitPatchInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Unit updated.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PoolUnit"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "delete": {
        "operationId": "poolUnitDelete",
        "tags": [
          "Pool CRUD"
        ],
        "summary": "Remove a catalogue line item",
        "description": "Bearer + organiser. Same guards as PATCH (zero reservations, DRAFT/FORMING).",
        "responses": {
          "200": {
            "description": "Unit deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "deleted": {
                              "type": "boolean",
                              "enum": [
                                true
                              ]
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/pools/{id}/disputes": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "poolDisputesList",
        "tags": [
          "Escrow"
        ],
        "summary": "List a pool's disputes",
        "description": "Bearer (member or organiser). The GROUPS off-chain dispute ledger.",
        "responses": {
          "200": {
            "description": "Disputes.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/PoolDispute"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "post": {
        "operationId": "poolDisputeCreate",
        "tags": [
          "Escrow"
        ],
        "summary": "File a dispute (GROUPS, off-chain)",
        "description": "Bearer (member or organiser). Records a SolidarityPoolDispute and sets the pool DISPUTED, which HOLDS the escrow release. Ledger-only — it does NOT execute money splits (Kudu never arbitrates). The CONTRACT-type on-chain dispute flow (`/contract/dispute/*`) is a separate mechanism and is out of scope for group-buys.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DisputeCreateInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dispute filed.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PoolDispute"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/pools/{id}/reservations/{reservationId}/no-show": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "reservationId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "reservationNoShow",
        "tags": [
          "Reservation"
        ],
        "summary": "Mark a reservation no-show (CONTAINER intake)",
        "description": "Bearer + organiser. CONTAINER mode only. Buyer paid but didn't deliver cargo to the depot; flips PAID → NO_SHOW and schedules an on-chain refund after the grace period. Requires reservation PAID and pool ACTIVE.\n",
        "responses": {
          "200": {
            "description": "Marked no-show.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "NO_SHOW"
                              ]
                            },
                            "refundScheduled": {
                              "type": "boolean"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/pools/{id}/reservations/{reservationId}/intake-received": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "reservationId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "reservationIntakeReceived",
        "tags": [
          "Reservation"
        ],
        "summary": "Mark cargo intake received (CONTAINER)",
        "description": "Bearer + organiser. CONTAINER mode only. Marks the buyer's cargo delivered to the depot (PAID → INTAKE_RECEIVED). Gates confirm-order. Requires reservation PAID and pool ACTIVE.\n",
        "responses": {
          "200": {
            "description": "Intake recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/SuccessEnvelope"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "INTAKE_RECEIVED"
                              ]
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "JWT in `Authorization: Bearer <jwt>` (HS256, 7-day). First-party callers may use the `kudu_session` cookie instead."
      },
      "webhookSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "Sendcloud-Signature",
        "description": "Per-provider HMAC-SHA256 (or shared-secret) signature header; the exact header name varies by provider."
      }
    },
    "parameters": {
      "XKuduTenant": {
        "name": "X-Kudu-Tenant",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "default": "kudu"
        },
        "description": "Whitelabel tenant slug (e.g. `your-tenant`). Defaults to `kudu`. Unknown slugs fall back to the default tenant."
      },
      "PageParam": {
        "name": "page",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        }
      },
      "LimitParam": {
        "name": "limit",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20
        }
      },
      "QParam": {
        "name": "q",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Free-text search."
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing/invalid authentication.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Authenticated but not permitted.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found (admin / hidden routes also return 404 to non-authorised callers).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "NotFoundWhenGated": {
        "description": "Not found. Also returned when the route is whitelabel-gated and the whitelabel toggle is off — the surface is hidden rather than 403'd.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "ValidationError": {
        "description": "Request validation failed (Zod). `errors` holds per-field messages.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "Conflict": {
        "description": "Conflict (idempotency / duplicate / already-in-state).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "Upstream dependency unavailable / not configured.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "BadGateway": {
        "description": "Upstream (e.g. Horizon) unreachable.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "ServerError": {
        "description": "Internal error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      }
    },
    "schemas": {
      "SuccessEnvelope": {
        "type": "object",
        "required": [
          "success",
          "data"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "data": {}
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": [
          "success",
          "error"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "string"
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer"
          },
          "hasMore": {
            "type": "boolean"
          }
        }
      },
      "PaginatedData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {}
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "PoolType": {
        "type": "string",
        "enum": [
          "FUNDING",
          "GROUPS",
          "CIRCLE",
          "CONTRACT"
        ]
      },
      "PoolStatus": {
        "type": "string",
        "enum": [
          "DRAFT",
          "INCUBATION",
          "PENDING_ACCEPT",
          "FORMING",
          "ACTIVE",
          "PAUSED",
          "RELEASING",
          "COMPLETED",
          "DISPUTED",
          "CANCELLED",
          "DISSOLVED",
          "EXPIRED",
          "DORMANT"
        ]
      },
      "PoolMarketplaceVisibility": {
        "type": "string",
        "enum": [
          "PRIVATE",
          "LISTED",
          "FEATURED"
        ]
      },
      "ReservationStatus": {
        "type": "string",
        "enum": [
          "PENDING",
          "PAID",
          "INTAKE_RECEIVED",
          "DELIVERED",
          "CANCELLED",
          "NO_SHOW",
          "REFUNDED"
        ]
      },
      "EscrowRule": {
        "type": "string",
        "enum": [
          "on-buy",
          "on-delivery",
          "50-50",
          "milestones"
        ]
      },
      "PaymentMethod": {
        "type": "string",
        "enum": [
          "EURC",
          "sepa",
          "card",
          "momo"
        ]
      },
      "SubscriptionTier": {
        "type": "string",
        "enum": [
          "decouverte",
          "standard",
          "pro",
          "premium"
        ]
      },
      "InvoiceKind": {
        "type": "string",
        "enum": [
          "GOODS",
          "COMMISSION",
          "PLATFORM_FEE",
          "SUBSCRIPTION",
          "RELAIS_FEE"
        ]
      },
      "MandateKind": {
        "type": "string",
        "enum": [
          "FEE",
          "COMMISSION",
          "RELAIS"
        ]
      },
      "MandateStatus": {
        "type": "string",
        "enum": [
          "ACCEPTED",
          "REVOKED"
        ]
      },
      "AccountType": {
        "type": "string",
        "enum": [
          "CONSUMER",
          "BUSINESS"
        ],
        "description": "User.accountType (commission-eligibility axis)."
      },
      "MerchantAccountType": {
        "type": "string",
        "enum": [
          "STANDARD",
          "GROUPS_MERCHANT"
        ],
        "description": "MerchantProfile.accountType (distinct from User.accountType)."
      },
      "UserRole": {
        "type": "string",
        "enum": [
          "user",
          "agent",
          "distributor",
          "organiser",
          "relais_operator"
        ]
      },
      "UserStatus": {
        "type": "string",
        "enum": [
          "pending_verification",
          "active",
          "suspended",
          "blocked",
          "inactive",
          "rejected",
          "deleted"
        ]
      },
      "RelaisOperatorStatus": {
        "type": "string",
        "enum": [
          "PENDING",
          "ACTIVE",
          "REJECTED",
          "SUSPENDED"
        ]
      },
      "EscrowDepositStatus": {
        "type": "string",
        "enum": [
          "HELD",
          "DRAWING",
          "REFUNDED",
          "DEPLETED"
        ]
      },
      "Currency": {
        "type": "string",
        "enum": [
          "USDC",
          "USDT",
          "EURC",
          "XOF",
          "BTC"
        ]
      },
      "SimpleRegisterInput": {
        "type": "object",
        "required": [
          "email",
          "password",
          "firstName",
          "lastName"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string",
            "minLength": 8
          },
          "firstName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "lastName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "country": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "description": "ISO country; defaults FR."
          },
          "accountType": {
            "$ref": "#/components/schemas/AccountType"
          },
          "role": {
            "type": "string",
            "enum": [
              "user",
              "organiser",
              "relais_operator"
            ],
            "default": "user"
          },
          "companyName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "description": "Required for BUSINESS."
          },
          "siret": {
            "type": "string",
            "pattern": "^\\d{14}$",
            "description": "FR business; required if BUSINESS + FR."
          },
          "taxCountry": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2
          },
          "taxId": {
            "type": "string",
            "minLength": 4,
            "maxLength": 40,
            "description": "Non-FR business tax id."
          },
          "rccm": {
            "type": "string",
            "minLength": 3,
            "maxLength": 40,
            "description": "Registre du Commerce (RCCM) — pan-African business registry number; an alternative to a foreign tax id for non-FR BUSINESS accounts."
          },
          "acceptFeeMandate": {
            "type": "boolean",
            "description": "Records the FEE mandate at signup (BUSINESS only)."
          }
        }
      },
      "AuthTokenResponse": {
        "type": "object",
        "properties": {
          "deviceId": {
            "type": "string"
          },
          "token": {
            "type": "string",
            "description": "7-day JWT."
          },
          "user": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "firstName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "lastName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "displayName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "role": {
                "$ref": "#/components/schemas/UserRole"
              },
              "accountType": {
                "$ref": "#/components/schemas/AccountType"
              },
              "avatarUrl": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        }
      },
      "AuthMeResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string"
          },
          "user": {
            "type": "object",
            "description": "Rich profile (subset shown; see auth/me handler for the full field list).",
            "properties": {
              "id": {
                "type": "string"
              },
              "phone": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "firstName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "lastName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "displayName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "avatarUrl": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "status": {
                "$ref": "#/components/schemas/UserStatus"
              },
              "role": {
                "$ref": "#/components/schemas/UserRole"
              },
              "accountType": {
                "$ref": "#/components/schemas/AccountType"
              },
              "kycStatus": {
                "type": "string"
              },
              "kycTier": {
                "type": "string"
              },
              "region": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "countryId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "baseCurrency": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "phoneVerified": {
                "type": "boolean"
              },
              "emailVerified": {
                "type": "boolean"
              },
              "verificationLevel": {
                "type": "integer"
              },
              "hasPin": {
                "type": "boolean"
              },
              "hasPassword": {
                "type": "boolean"
              },
              "hasEncryptedMnemonic": {
                "type": "boolean"
              },
              "hasStellarWallet": {
                "type": "boolean"
              },
              "stellarStatus": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "onboardingStep": {
                "type": "integer"
              },
              "onboardingComplete": {
                "type": "boolean"
              },
              "isAgent": {
                "type": "boolean"
              }
            }
          },
          "spending": {
            "type": "object",
            "properties": {
              "dailyUsedXof": {
                "type": "number"
              },
              "dailyLimitXof": {
                "type": "number"
              },
              "monthlyUsedXof": {
                "type": "number"
              },
              "monthlyLimitXof": {
                "type": "number"
              }
            }
          },
          "wallet": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "balances": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "addresses": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "agent": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          }
        }
      },
      "OrganiserGrant": {
        "type": "object",
        "description": "Buyer-as-organiser 1-EURC activation grant.",
        "properties": {
          "grantId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "AWAITING_SIGNATURE",
              "SETTLED",
              "FAILED"
            ]
          },
          "amount": {
            "type": "string",
            "example": "1.0000000"
          },
          "currency": {
            "type": "string",
            "enum": [
              "EURC"
            ]
          },
          "feeAccount": {
            "type": "string"
          },
          "buyerPublicKey": {
            "type": [
              "string",
              "null"
            ]
          },
          "unsignedXdr": {
            "type": [
              "string",
              "null"
            ],
            "description": "Freshly rebuilt while AWAITING_SIGNATURE."
          }
        }
      },
      "OrganiserGrantPrepareResult": {
        "type": "object",
        "properties": {
          "grantId": {
            "type": "string"
          },
          "nonce": {
            "type": "string",
            "format": "uuid"
          },
          "unsignedXdr": {
            "type": "string"
          },
          "amount": {
            "type": "string",
            "example": "1.0000000"
          },
          "currency": {
            "type": "string",
            "enum": [
              "EURC"
            ]
          },
          "buyerPublicKey": {
            "type": "string"
          },
          "feeAccount": {
            "type": "string"
          }
        }
      },
      "Mandate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "mandantUserId": {
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/MandateKind"
          },
          "version": {
            "type": "string"
          },
          "textHash": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/MandateStatus"
          },
          "acceptedAt": {
            "type": "string",
            "format": "date-time"
          },
          "acceptedIp": {
            "type": [
              "string",
              "null"
            ]
          },
          "revokedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "MerchantCard": {
        "type": "object",
        "description": "Public catalogue projection of a MerchantProfile.",
        "properties": {
          "slug": {
            "type": "string"
          },
          "businessName": {
            "type": "string"
          },
          "businessType": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "logoUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "district": {
            "type": [
              "string",
              "null"
            ]
          },
          "primaryCurrency": {
            "type": "string"
          },
          "storefrontHeadline": {
            "type": [
              "string",
              "null"
            ]
          },
          "storefrontTagline": {
            "type": [
              "string",
              "null"
            ]
          },
          "storefrontLinks": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "[{label,url,position}]"
          },
          "brandPrimary": {
            "type": [
              "string",
              "null"
            ]
          },
          "brandAccent": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "MerchantProfile": {
        "type": "object",
        "description": "Full merchant profile (subset of fields; see prisma MerchantProfile).",
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "tenantId": {
            "type": "string"
          },
          "businessName": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "businessType": {
            "type": "string",
            "enum": [
              "RESTAURANT",
              "SHOP",
              "SERVICE",
              "FREELANCE",
              "OTHER"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "logoUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "district": {
            "type": [
              "string",
              "null"
            ]
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "countryId": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "whatsapp": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "acceptedCurrencies": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "primaryCurrency": {
            "type": "string"
          },
          "feeHandling": {
            "type": "string",
            "enum": [
              "RECEIVER_PAYS",
              "SENDER_PAYS",
              "SPLIT",
              "INCLUDED"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "SUSPENDED"
            ]
          },
          "escrowEnabled": {
            "type": "boolean"
          },
          "escrowWindowHours": {
            "type": "integer"
          },
          "accountType": {
            "$ref": "#/components/schemas/MerchantAccountType"
          },
          "customDomain": {
            "type": [
              "string",
              "null"
            ]
          },
          "storefrontHeadline": {
            "type": [
              "string",
              "null"
            ]
          },
          "storefrontTagline": {
            "type": [
              "string",
              "null"
            ]
          },
          "storefrontAbout": {
            "type": [
              "string",
              "null"
            ]
          },
          "storefrontLinks": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "brandPrimary": {
            "type": [
              "string",
              "null"
            ]
          },
          "brandAccent": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "MerchantProfileUpdateInput": {
        "type": "object",
        "properties": {
          "businessName": {
            "type": "string"
          },
          "businessType": {
            "type": "string",
            "enum": [
              "RESTAURANT",
              "SHOP",
              "SERVICE",
              "FREELANCE",
              "OTHER"
            ]
          },
          "description": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "whatsapp": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "acceptedCurrencies": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "primaryCurrency": {
            "type": "string"
          },
          "feeHandling": {
            "type": "string",
            "enum": [
              "SENDER_PAYS",
              "RECEIVER_PAYS"
            ]
          },
          "escrowEnabled": {
            "type": "boolean"
          },
          "escrowWindowHours": {
            "type": "integer",
            "minimum": 1,
            "maximum": 168
          }
        }
      },
      "GroupsConfig": {
        "type": "object",
        "description": "GROUPS template `config` blob (groupsConfigSchema).",
        "properties": {
          "groupBuyType": {
            "type": "string",
            "enum": [
              "BULK_VENDOR",
              "CONTAINER_IMPORT",
              "COURIER_CONSOLIDATED",
              "DISTRIBUTION_PACK",
              "SERVICE_BOOKING"
            ]
          },
          "buyerCurrency": {
            "type": "string"
          },
          "supplier": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "phone": {
                "type": "string"
              },
              "country": {
                "type": "string"
              }
            }
          },
          "orderDeadline": {
            "type": "string",
            "format": "date-time"
          },
          "deliveryEstimate": {
            "type": "string",
            "format": "date-time"
          },
          "fulfillmentWindowDays": {
            "type": "number",
            "maximum": 120
          },
          "minimumOrderAmount": {
            "type": "number"
          },
          "maximumOrderAmount": {
            "type": "number"
          },
          "deliveryMethod": {
            "type": "string",
            "enum": [
              "PICKUP",
              "DELIVERY",
              "MIXED"
            ]
          },
          "notes": {
            "type": "string"
          },
          "shippingMode": {
            "type": "string",
            "enum": [
              "NONE",
              "CONTAINER",
              "COURIER"
            ]
          },
          "allowedCarriers": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "relais": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "kind": {
                  "type": "string"
                },
                "address": {
                  "type": "string"
                },
                "distanceKm": {
                  "type": "number"
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "carrier",
                    "communal",
                    "merchant"
                  ]
                },
                "carrier": {
                  "type": "string"
                },
                "externalId": {
                  "type": "string"
                },
                "operatorId": {
                  "type": "string"
                },
                "geoLat": {
                  "type": "number"
                },
                "geoLng": {
                  "type": "number"
                }
              }
            }
          },
          "sellerLinks": {
            "type": "object",
            "properties": {
              "website": {
                "type": "string"
              },
              "facebook": {
                "type": "string"
              },
              "linkedin": {
                "type": "string"
              },
              "other": {
                "type": "string"
              }
            }
          },
          "documents": {
            "type": "array",
            "maxItems": 3,
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "size": {
                  "type": "integer"
                }
              }
            }
          },
          "escrow": {
            "type": "object",
            "description": "On-chain metadata, populated at publish (never user-input).",
            "properties": {
              "recipientPublicKey": {
                "type": "string"
              },
              "sponsorPublicKey": {
                "type": "string"
              },
              "mediatorPublicKey": {
                "type": "string"
              },
              "organiserPublicKey": {
                "type": "string"
              },
              "publishTxHash": {
                "type": "string"
              },
              "createdAt": {
                "type": "string"
              }
            }
          }
        },
        "additionalProperties": true
      },
      "PoolUnit": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "poolId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "unitType": {
            "type": "string"
          },
          "unitLabel": {
            "type": "string"
          },
          "pricePerUnit": {
            "type": "string",
            "description": "Decimal as string."
          },
          "totalUnits": {
            "type": "integer"
          },
          "reservedUnits": {
            "type": "integer"
          },
          "receivedUnits": {
            "type": "integer"
          },
          "imageUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "maxWeightKg": {
            "type": [
              "string",
              "null"
            ]
          },
          "supplierName": {
            "type": [
              "string",
              "null"
            ]
          },
          "estimatedDelivery": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "PoolPickupPoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": [
              "string",
              "null"
            ]
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "distanceKm": {
            "type": [
              "number",
              "null"
            ]
          },
          "source": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "carrier",
              "communal",
              "merchant"
            ]
          },
          "carrier": {
            "type": [
              "string",
              "null"
            ]
          },
          "externalId": {
            "type": [
              "string",
              "null"
            ]
          },
          "operatorId": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "GroupBuy": {
        "type": "object",
        "description": "A SolidarityPool (group-buy spine). Field set varies by route (full vs catalogue projection).",
        "properties": {
          "id": {
            "type": "string"
          },
          "ref": {
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/PoolType"
          },
          "status": {
            "$ref": "#/components/schemas/PoolStatus"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "organiserId": {
            "type": "string"
          },
          "sellerId": {
            "type": [
              "string",
              "null"
            ]
          },
          "payeeAddress": {
            "type": [
              "string",
              "null"
            ]
          },
          "tenantId": {
            "type": "string"
          },
          "primaryCurrency": {
            "type": "string"
          },
          "poolCurrency": {
            "type": "string",
            "enum": [
              "EURC_ONLY",
              "USDC_ONLY",
              "BOTH"
            ]
          },
          "unitPrice": {
            "type": [
              "string",
              "null"
            ]
          },
          "soloPrice": {
            "type": [
              "string",
              "null"
            ]
          },
          "unitLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "productLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "goalAmount": {
            "type": [
              "string",
              "null"
            ]
          },
          "commissionPercent": {
            "type": "string"
          },
          "organiserCommissionPercent": {
            "type": "string"
          },
          "relaisOperatorId": {
            "type": [
              "string",
              "null"
            ]
          },
          "relaisCommissionPercent": {
            "type": "string"
          },
          "membershipMode": {
            "type": "string",
            "enum": [
              "LOCKED_LIST",
              "INVITE_LINK",
              "OPEN"
            ]
          },
          "maxMembers": {
            "type": [
              "integer",
              "null"
            ]
          },
          "memberCount": {
            "type": "integer"
          },
          "deadline": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "marketplaceVisibility": {
            "$ref": "#/components/schemas/PoolMarketplaceVisibility"
          },
          "onChainEnabled": {
            "type": "boolean"
          },
          "config": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/GroupsConfig"
              },
              {
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ]
          },
          "units": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PoolUnit"
            }
          },
          "pickupPoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PoolPickupPoint"
            }
          },
          "organiser": {
            "type": "object",
            "properties": {
              "displayName": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "archivedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "GroupBuyCard": {
        "allOf": [
          {
            "$ref": "#/components/schemas/GroupBuy"
          },
          {
            "description": "Public catalogue projection (config redacted; members reduced to names)."
          }
        ]
      },
      "PoolCreateInput": {
        "type": "object",
        "required": [
          "type",
          "name"
        ],
        "properties": {
          "type": {
            "$ref": "#/components/schemas/PoolType"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "description": {
            "type": "string",
            "maxLength": 2000
          },
          "category": {
            "type": "string"
          },
          "poolCurrency": {
            "type": "string",
            "enum": [
              "EURC_ONLY",
              "USDC_ONLY",
              "BOTH"
            ],
            "default": "EURC_ONLY"
          },
          "primaryCurrency": {
            "type": "string",
            "enum": [
              "USDC",
              "EURC"
            ],
            "default": "EURC"
          },
          "goalType": {
            "type": "string",
            "enum": [
              "HARD",
              "SOFT_WITH_MIN",
              "FLEXIBLE",
              "NONE"
            ],
            "default": "NONE"
          },
          "goalAmount": {
            "type": "number"
          },
          "softMinAmount": {
            "type": "number"
          },
          "commissionPercent": {
            "type": "number",
            "minimum": 0,
            "maximum": 10,
            "default": 2
          },
          "commissionSplits": {
            "type": "object",
            "properties": {
              "kudu": {
                "type": "number",
                "minimum": 50,
                "maximum": 100
              },
              "solidarity": {
                "type": "number",
                "minimum": 0,
                "maximum": 50
              },
              "organiser": {
                "type": "number",
                "minimum": 0,
                "maximum": 20
              },
              "referral": {
                "type": "number",
                "minimum": 0,
                "maximum": 20
              }
            }
          },
          "sellerId": {
            "type": "string"
          },
          "payeeAddress": {
            "type": "string"
          },
          "organiserCommissionPercent": {
            "type": "number",
            "minimum": 0,
            "maximum": 20,
            "default": 0
          },
          "relaisOperatorId": {
            "type": "string"
          },
          "relaisCommissionPercent": {
            "type": "number",
            "minimum": 0,
            "maximum": 20,
            "default": 0
          },
          "membershipMode": {
            "type": "string",
            "enum": [
              "LOCKED_LIST",
              "INVITE_LINK",
              "OPEN"
            ],
            "default": "LOCKED_LIST"
          },
          "maxMembers": {
            "type": "integer"
          },
          "payoutOrder": {
            "type": "string",
            "enum": [
              "FIXED",
              "RANDOM",
              "MILESTONE",
              "SINGLE",
              "PROPORTIONAL"
            ],
            "default": "SINGLE"
          },
          "validatorMode": {
            "type": "string",
            "enum": [
              "NONE",
              "ROTATING",
              "ELECTED",
              "RECIPIENT",
              "ORGANISER"
            ],
            "default": "NONE"
          },
          "contributorVisibility": {
            "type": "string",
            "enum": [
              "ANONYMOUS",
              "SEMI_PUBLIC",
              "PUBLIC"
            ],
            "default": "PUBLIC"
          },
          "retractionPolicy": {
            "type": "string",
            "enum": [
              "FREE_BEFORE_GOAL",
              "PENALTY",
              "NONE"
            ],
            "default": "NONE"
          },
          "retractionPenalty": {
            "type": "number",
            "minimum": 0,
            "maximum": 50
          },
          "deadline": {
            "type": "string",
            "format": "date-time"
          },
          "startDate": {
            "type": "string",
            "format": "date-time"
          },
          "releaseDate": {
            "type": "string",
            "format": "date-time"
          },
          "onChainEnabled": {
            "type": "boolean",
            "default": false
          },
          "dormancyThresholdDays": {
            "type": "integer"
          },
          "config": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/GroupsConfig"
              },
              {
                "type": "object",
                "additionalProperties": true
              }
            ]
          },
          "marketplaceVisibility": {
            "$ref": "#/components/schemas/PoolMarketplaceVisibility"
          },
          "country": {
            "type": "string",
            "maxLength": 64
          },
          "units": {
            "type": "array",
            "description": "Catalogue line items to create with the pool.",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "MerchantPoolCreateInput": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PoolCreateInput"
          },
          {
            "type": "object",
            "properties": {
              "sellerIdentifier": {
                "type": "string",
                "maxLength": 200,
                "description": "Seller email/phone → resolved to sellerId at the route."
              },
              "sellerMerchantSlug": {
                "type": "string",
                "maxLength": 200,
                "description": "Vendor slug → resolved to sellerId (buyer-as-organiser)."
              },
              "acceptCommissionMandate": {
                "type": "boolean",
                "description": "Records the COMMISSION mandate on a brokered paid pool."
              }
            }
          }
        ]
      },
      "PoolUpdateInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "description": {
            "type": "string",
            "maxLength": 2000
          },
          "category": {
            "type": "string"
          },
          "goalAmount": {
            "type": "number"
          },
          "softMinAmount": {
            "type": "number"
          },
          "maxMembers": {
            "type": "integer"
          },
          "deadline": {
            "type": "string",
            "format": "date-time"
          },
          "startDate": {
            "type": "string",
            "format": "date-time"
          },
          "releaseDate": {
            "type": "string",
            "format": "date-time"
          },
          "config": {
            "type": "object",
            "additionalProperties": true
          },
          "marketplaceVisibility": {
            "type": "string",
            "enum": [
              "PRIVATE",
              "LISTED"
            ]
          },
          "country": {
            "type": "string",
            "maxLength": 64
          }
        }
      },
      "MerchantPoolUpdateInput": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PoolUpdateInput"
          },
          {
            "type": "object",
            "properties": {
              "sellerIdentifier": {
                "type": "string",
                "maxLength": 200
              },
              "sellerMerchantSlug": {
                "type": "string",
                "maxLength": 200
              },
              "sellerId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "payeeAddress": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "organiserCommissionPercent": {
                "type": "number",
                "minimum": 0,
                "maximum": 20
              },
              "relaisOperatorId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "relaisCommissionPercent": {
                "type": "number",
                "minimum": 0,
                "maximum": 20
              }
            }
          }
        ]
      },
      "ReservePreflightResult": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "reason": {
            "type": "string"
          },
          "accountExists": {
            "type": "boolean"
          },
          "hasTrustline": {
            "type": "boolean"
          },
          "balanceSufficient": {
            "type": "boolean"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "amountRequired": {
            "type": "string"
          },
          "activeReservations": {
            "type": "integer"
          },
          "remainingReservations": {
            "type": "integer"
          },
          "remainingCapacity": {
            "type": "integer"
          },
          "needsStellarSetup": {
            "type": "boolean"
          },
          "stockAvailable": {
            "type": "integer"
          }
        }
      },
      "ReservePrepareInput": {
        "type": "object",
        "required": [
          "quantity"
        ],
        "properties": {
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100000
          },
          "nonce": {
            "type": "string",
            "format": "uuid"
          },
          "cargoDescription": {
            "type": "string",
            "maxLength": 2000
          },
          "pickupPointId": {
            "type": "string"
          },
          "pickupPoint": {
            "type": "object",
            "required": [
              "externalId",
              "carrier",
              "name"
            ],
            "properties": {
              "externalId": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "carrier": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64
              },
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "address": {
                "type": "string",
                "maxLength": 400
              },
              "lat": {
                "type": "number"
              },
              "lng": {
                "type": "number"
              }
            }
          }
        }
      },
      "ReservePrepareResult": {
        "type": "object",
        "properties": {
          "reservationId": {
            "type": "string"
          },
          "nonce": {
            "type": "string"
          },
          "halfSignedCreateXdr": {
            "type": "string",
            "description": "Treasury-signed CB-create XDR awaiting the buyer signature."
          },
          "amount": {
            "type": "string",
            "description": "7-decimal."
          },
          "currency": {
            "type": "string",
            "enum": [
              "USDC",
              "EURC"
            ]
          },
          "unlockAtUnix": {
            "type": "integer"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "needsBuyerSignature": {
            "type": "boolean"
          },
          "buyerPublicKey": {
            "type": "string"
          }
        }
      },
      "ReserveSubmitResult": {
        "type": "object",
        "properties": {
          "reservationId": {
            "type": "string"
          },
          "balanceId": {
            "type": "string"
          },
          "createTxHash": {
            "type": "string"
          },
          "unsignedReclaimXdr": {
            "type": "string"
          },
          "unlockAtUnix": {
            "type": "integer"
          },
          "needsBuyerSignature": {
            "type": "boolean"
          },
          "buyerPublicKey": {
            "type": "string"
          }
        }
      },
      "Reservation": {
        "type": "object",
        "description": "A SolidarityPoolUnitReservation (reclaim XDR always redacted in API responses).",
        "properties": {
          "id": {
            "type": "string"
          },
          "unitId": {
            "type": "string"
          },
          "poolId": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "memberId": {
            "type": "string"
          },
          "quantity": {
            "type": "integer"
          },
          "amountPaid": {
            "type": "string"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "status": {
            "$ref": "#/components/schemas/ReservationStatus"
          },
          "buyerPublicKey": {
            "type": "string"
          },
          "balanceId": {
            "type": [
              "string",
              "null"
            ]
          },
          "createTxHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "pickupPointId": {
            "type": [
              "string",
              "null"
            ]
          },
          "cargoDescription": {
            "type": [
              "string",
              "null"
            ]
          },
          "nonce": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "receiptConfirmedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "deliverySource": {
            "type": [
              "string",
              "null"
            ]
          },
          "deliveryProvider": {
            "type": [
              "string",
              "null"
            ]
          },
          "trackingRef": {
            "type": [
              "string",
              "null"
            ]
          },
          "shippedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "user": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "displayName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "firstName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "phone": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "unit": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          }
        }
      },
      "Order": {
        "type": "object",
        "description": "Buyer order-dashboard row (tenant/my-orders).",
        "properties": {
          "reservationId": {
            "type": "string"
          },
          "poolId": {
            "type": "string"
          },
          "poolRef": {
            "type": "string"
          },
          "poolName": {
            "type": "string"
          },
          "poolStatus": {
            "$ref": "#/components/schemas/PoolStatus"
          },
          "unitId": {
            "type": "string"
          },
          "unitName": {
            "type": "string"
          },
          "unitLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "quantity": {
            "type": "integer"
          },
          "amount": {
            "type": "string"
          },
          "amountDisplay": {
            "type": "string"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "status": {
            "$ref": "#/components/schemas/ReservationStatus"
          },
          "escrow": {
            "type": "object",
            "properties": {
              "statusCode": {
                "type": "string"
              },
              "statusLabel": {
                "type": "string"
              },
              "step": {
                "type": "integer"
              },
              "stepCount": {
                "type": "integer"
              },
              "releasedPct": {
                "type": "number"
              },
              "isDone": {
                "type": "boolean"
              }
            }
          },
          "balanceId": {
            "type": [
              "string",
              "null"
            ]
          },
          "pickupPoint": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "PendingReservation": {
        "type": "object",
        "properties": {
          "reservationId": {
            "type": "string"
          },
          "poolId": {
            "type": "string"
          },
          "unitId": {
            "type": "string"
          },
          "poolName": {
            "type": "string"
          },
          "poolRef": {
            "type": "string"
          },
          "unitName": {
            "type": "string"
          },
          "unitLabel": {
            "type": [
              "string",
              "null"
            ]
          },
          "quantity": {
            "type": "integer"
          },
          "amount": {
            "type": "string"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "status": {
            "$ref": "#/components/schemas/ReservationStatus"
          },
          "buyerPublicKey": {
            "type": "string"
          },
          "createXdr": {
            "type": "string",
            "description": "Half-signed CB-create XDR to co-sign."
          },
          "needsBuyerSignature": {
            "type": "boolean"
          },
          "createTxHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "balanceId": {
            "type": [
              "string",
              "null"
            ]
          },
          "pickupPoint": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ReleaseSplit": {
        "type": "object",
        "description": "A payout leg in the weighted release.",
        "properties": {
          "amount": {
            "type": "string"
          },
          "publicKey": {
            "type": "string"
          }
        }
      },
      "ConfirmOrderPrepareResult": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string"
          },
          "halfSignedXdrs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "organiserPublicKey": {
            "type": "string"
          },
          "totalPaid": {
            "type": "string"
          },
          "shape": {
            "type": "string",
            "description": "self-organized | business-broker | consumer-org"
          },
          "seller": {
            "$ref": "#/components/schemas/ReleaseSplit"
          },
          "organiser": {
            "$ref": "#/components/schemas/ReleaseSplit"
          },
          "relais": {
            "$ref": "#/components/schemas/ReleaseSplit"
          },
          "platform": {
            "$ref": "#/components/schemas/ReleaseSplit"
          },
          "batchCount": {
            "type": "integer"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          }
        }
      },
      "ArmKeylessPrepareResult": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string"
          },
          "deferred": {
            "type": "boolean"
          },
          "halfSignedArmXdr": {
            "type": "string"
          },
          "organiserPublicKey": {
            "type": "string"
          },
          "minTimeUnix": {
            "type": "integer"
          },
          "maxTimeUnix": {
            "type": "integer"
          },
          "eligibleAtUnix": {
            "type": "integer"
          },
          "totalPaid": {
            "type": "string"
          },
          "shape": {
            "type": "string"
          },
          "seller": {
            "$ref": "#/components/schemas/ReleaseSplit"
          },
          "organiser": {
            "$ref": "#/components/schemas/ReleaseSplit"
          },
          "platform": {
            "$ref": "#/components/schemas/ReleaseSplit"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          }
        }
      },
      "EscrowDeposit": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "poolId": {
            "type": "string"
          },
          "tenantId": {
            "type": "string"
          },
          "merchantId": {
            "type": "string"
          },
          "amountEurCents": {
            "type": "integer"
          },
          "consumedCents": {
            "type": "integer"
          },
          "remainingCents": {
            "type": "integer"
          },
          "estimatedCostCents": {
            "type": "integer"
          },
          "stellarContractId": {
            "type": [
              "string",
              "null"
            ]
          },
          "escrowRule": {
            "$ref": "#/components/schemas/EscrowRule"
          },
          "status": {
            "$ref": "#/components/schemas/EscrowDepositStatus"
          },
          "signatureHandoff": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "url": {
                "type": "string"
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              },
              "status": {
                "type": "string"
              },
              "reason": {
                "type": "string"
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "settledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "FeeResolveInput": {
        "type": "object",
        "required": [
          "sectorId",
          "orderAmountCents",
          "escrowRule",
          "paymentMethod"
        ],
        "properties": {
          "sectorId": {
            "type": "string",
            "minLength": 1
          },
          "orderAmountCents": {
            "type": "integer",
            "minimum": 0
          },
          "escrowRule": {
            "$ref": "#/components/schemas/EscrowRule"
          },
          "paymentMethod": {
            "$ref": "#/components/schemas/PaymentMethod"
          },
          "subscriptionTier": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubscriptionTier"
              },
              {
                "type": "null"
              }
            ]
          },
          "lifetimeVolumeCents": {
            "type": [
              "integer",
              "null"
            ]
          },
          "tenureMonths": {
            "type": [
              "integer",
              "null"
            ]
          },
          "maxPoolMembers": {
            "type": [
              "integer",
              "null"
            ]
          },
          "regionCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "promoCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "disputeRatePct": {
            "type": [
              "number",
              "null"
            ]
          },
          "merchantSlug": {
            "type": [
              "string",
              "null"
            ],
            "description": "Deep-merges the merchant's fee overrides."
          }
        }
      },
      "FeeBreakdown": {
        "type": "object",
        "properties": {
          "basePercent": {
            "type": "number"
          },
          "sectorCoeff": {
            "type": "number"
          },
          "volumeCoeff": {
            "type": "number"
          },
          "tenureCoeff": {
            "type": "number"
          },
          "poolSizeCoeff": {
            "type": "number"
          },
          "escrowRuleCoeff": {
            "type": "number"
          },
          "paymentMethodCoeff": {
            "type": "number"
          },
          "subscriptionTierCoeff": {
            "type": "number"
          },
          "promoCoeff": {
            "type": "number"
          },
          "regionCoeff": {
            "type": "number"
          },
          "fixedSectorAdjust": {
            "type": "number"
          },
          "riskByDisputeRate": {
            "type": "number"
          },
          "clampApplied": {
            "type": "boolean"
          }
        }
      },
      "FeeResolved": {
        "type": "object",
        "properties": {
          "effectivePercent": {
            "type": "number"
          },
          "fixedCents": {
            "type": "integer"
          },
          "totalCents": {
            "type": "integer"
          },
          "breakdown": {
            "$ref": "#/components/schemas/FeeBreakdown"
          }
        }
      },
      "EscrowQuoteResult": {
        "type": "object",
        "properties": {
          "escrowCostCents": {
            "type": "integer"
          },
          "bonneFoiCents": {
            "type": "integer"
          }
        }
      },
      "Invoice": {
        "type": "object",
        "description": "Invoice list projection (omits the heavy Factur-X XML).",
        "properties": {
          "id": {
            "type": "string"
          },
          "number": {
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/InvoiceKind"
          },
          "shape": {
            "type": [
              "string",
              "null"
            ]
          },
          "poolId": {
            "type": [
              "string",
              "null"
            ]
          },
          "payoutRole": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "SELLER",
              "ORGANISER",
              "RELAIS",
              "DISTRIBUTOR",
              "PLATFORM",
              "TRANSITAIRE",
              "OTHER"
            ]
          },
          "stellarTxHash": {
            "type": [
              "string",
              "null"
            ]
          },
          "issuerType": {
            "type": "string"
          },
          "issuerUserId": {
            "type": [
              "string",
              "null"
            ]
          },
          "issuerName": {
            "type": "string"
          },
          "recipientType": {
            "type": "string"
          },
          "recipientUserId": {
            "type": [
              "string",
              "null"
            ]
          },
          "recipientName": {
            "type": "string"
          },
          "currency": {
            "$ref": "#/components/schemas/Currency"
          },
          "netAmount": {
            "type": "string"
          },
          "vatTreatment": {
            "type": "string"
          },
          "vatRate": {
            "type": "string"
          },
          "vatBase": {
            "type": "string"
          },
          "vatAmount": {
            "type": "string"
          },
          "totalAmount": {
            "type": "string"
          },
          "selfBilled": {
            "type": "boolean"
          },
          "eReporting": {
            "type": "string"
          },
          "paStatus": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "issuedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "FacturXResult": {
        "type": "object",
        "properties": {
          "number": {
            "type": "string"
          },
          "filename": {
            "type": "string"
          },
          "contentType": {
            "type": "string",
            "example": "application/xml"
          },
          "xml": {
            "type": "string",
            "description": "EN16931 / Factur-X BASIC CII XML."
          }
        }
      },
      "ServicePoint": {
        "type": "object",
        "description": "Normalised Sendcloud carrier point-relais.",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "carrier": {
            "type": "string"
          },
          "carrierName": {
            "type": "string"
          },
          "carrierLogoUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "street": {
            "type": "string"
          },
          "houseNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "postalCode": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "lat": {
            "type": "number"
          },
          "lng": {
            "type": "number"
          },
          "distanceM": {
            "type": "number"
          },
          "shopType": {
            "type": [
              "string",
              "null"
            ]
          },
          "openingTimes": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          }
        }
      },
      "RelaisOperator": {
        "type": "object",
        "description": "the partner communal pickup host (SharedRelaisDTO projection).",
        "properties": {
          "id": {
            "type": "string"
          },
          "publicSlug": {
            "type": "string"
          },
          "operatorType": {
            "type": "string"
          },
          "operatorName": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "regionCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "departmentCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "postcode": {
            "type": [
              "string",
              "null"
            ]
          },
          "geo": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "lat": {
                "type": "number"
              },
              "lng": {
                "type": "number"
              }
            }
          },
          "openingWindows": {
            "type": [
              "string",
              "null"
            ]
          },
          "capacity": {
            "type": [
              "integer",
              "null"
            ]
          },
          "acceptedKinds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "verified": {
            "type": "boolean"
          },
          "status": {
            "$ref": "#/components/schemas/RelaisOperatorStatus"
          }
        }
      },
      "RelaisApplyInput": {
        "type": "object",
        "required": [
          "operatorType",
          "operatorName",
          "contactEmail",
          "relaisName",
          "address"
        ],
        "properties": {
          "operatorType": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "operatorName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "contactEmail": {
            "type": "string",
            "format": "email"
          },
          "contactPhone": {
            "type": "string"
          },
          "relaisName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "address": {
            "type": "string",
            "minLength": 1,
            "maxLength": 400
          },
          "regionCode": {
            "type": "string"
          },
          "departmentCode": {
            "type": "string"
          },
          "postcode": {
            "type": "string"
          },
          "geoLat": {
            "type": "number"
          },
          "geoLng": {
            "type": "number"
          },
          "openingWindows": {
            "type": "string",
            "maxLength": 400
          },
          "capacity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5000
          },
          "acceptedKinds": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "type": "string"
            }
          },
          "motivation": {
            "type": "string",
            "maxLength": 2000
          },
          "legalStatus": {
            "type": "string",
            "maxLength": 120
          },
          "erpReceivesPublic": {
            "type": "boolean"
          },
          "insuranceRef": {
            "type": "string",
            "maxLength": 200
          },
          "payoutAddress": {
            "type": "string",
            "maxLength": 120
          }
        }
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "type": "string",
                  "enum": [
                    "merchant",
                    "pool"
                  ]
                },
                "slug": {
                  "type": "string"
                },
                "score": {
                  "type": "number"
                },
                "row": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "popular": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "fallback": {
            "type": "boolean"
          },
          "mode": {
            "type": "string",
            "enum": [
              "normal",
              "short",
              "popular"
            ]
          },
          "total": {
            "type": "integer"
          }
        }
      },
      "PilotRequestInput": {
        "type": "object",
        "required": [
          "organization",
          "contactName",
          "email"
        ],
        "properties": {
          "segment": {
            "type": "string",
            "maxLength": 40
          },
          "organization": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "contactName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string",
            "maxLength": 40
          },
          "message": {
            "type": "string",
            "maxLength": 4000
          },
          "utm": {
            "type": "object",
            "properties": {
              "source": {
                "type": "string",
                "maxLength": 200
              },
              "medium": {
                "type": "string",
                "maxLength": 200
              },
              "campaign": {
                "type": "string",
                "maxLength": 200
              },
              "term": {
                "type": "string",
                "maxLength": 200
              },
              "content": {
                "type": "string",
                "maxLength": 200
              },
              "landingPath": {
                "type": "string",
                "maxLength": 500
              },
              "firstTouchAt": {
                "type": "string",
                "maxLength": 200
              }
            }
          }
        }
      },
      "PublishPrepareResult": {
        "type": "object",
        "properties": {
          "recipientPublicKey": {
            "type": "string"
          },
          "halfSignedXdr": {
            "type": "string"
          },
          "organiserPublicKey": {
            "type": "string"
          },
          "needsOrganiserSignature": {
            "type": "boolean"
          },
          "creationFeeAmount": {
            "type": "string"
          },
          "currency": {
            "type": "string",
            "enum": [
              "EURC",
              "USDC"
            ]
          },
          "claimGraceSeconds": {
            "type": "integer"
          }
        }
      },
      "UnitCreateInput": {
        "type": "object",
        "required": [
          "name",
          "unitType",
          "unitLabel",
          "pricePerUnit",
          "totalUnits"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "unitType": {
            "type": "string",
            "enum": [
              "weight",
              "count",
              "space",
              "volume"
            ]
          },
          "unitLabel": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "pricePerUnit": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 1000000000
          },
          "totalUnits": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 1000000
          },
          "maxWeightKg": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 1000000
          },
          "supplierName": {
            "type": "string",
            "maxLength": 200
          },
          "supplierPhone": {
            "type": "string",
            "maxLength": 40
          },
          "orderRef": {
            "type": "string",
            "maxLength": 200
          }
        }
      },
      "UnitPatchInput": {
        "type": "object",
        "description": "All fields optional; same constraints as UnitCreateInput.",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "unitType": {
            "type": "string",
            "enum": [
              "weight",
              "count",
              "space",
              "volume"
            ]
          },
          "unitLabel": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "pricePerUnit": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 1000000000
          },
          "totalUnits": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 1000000
          },
          "maxWeightKg": {
            "type": "number"
          },
          "supplierName": {
            "type": "string",
            "maxLength": 200
          },
          "supplierPhone": {
            "type": "string",
            "maxLength": 40
          },
          "orderRef": {
            "type": "string",
            "maxLength": 200
          }
        }
      },
      "PoolMember": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "poolId": {
            "type": "string"
          },
          "userId": {
            "type": [
              "string",
              "null"
            ]
          },
          "role": {
            "type": "string",
            "enum": [
              "ORGANISER",
              "CO_ORGANISER",
              "CONTRIBUTOR",
              "BENEFICIARY",
              "PARTICIPANT",
              "PAYER",
              "PROVIDER",
              "BUYER",
              "CONTRACT_PAYER"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "INVITED",
              "PENDING",
              "ACTIVE",
              "RECEIVED",
              "DEFAULTED",
              "SUSPENDED",
              "EXITED",
              "EXPELLED"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "unitsReserved": {
            "type": "integer"
          },
          "unitsReceived": {
            "type": "integer"
          },
          "joinedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "user": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "displayName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "avatarUrl": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        }
      },
      "DisputeCreateInput": {
        "type": "object",
        "required": [
          "category",
          "description"
        ],
        "properties": {
          "category": {
            "type": "string",
            "enum": [
              "MISSED_CONTRIBUTION",
              "PAYOUT_DELAY",
              "UNFAIR_ORDER",
              "FRAUD",
              "MILESTONE_QUALITY",
              "DELIVERY_ISSUE",
              "ORGANISER_MISCONDUCT",
              "OTHER"
            ]
          },
          "description": {
            "type": "string",
            "minLength": 10,
            "maxLength": 5000
          }
        }
      },
      "PoolDispute": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "poolId": {
            "type": "string"
          },
          "filedBy": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "e.g. OPEN (filed). Resolution is off-API."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}
