{
  "openapi": "3.1.0",
  "info": {
    "title": "Sendero Agent Tools",
    "version": "1.0.0",
    "description": "The Sendero tool registry — a single surface for travel booking, treasury rebalancing, OCR, trip-document verification, and guest-escrow settlement.\n\n## Authentication\n\nEvery call is authenticated with a Clerk-issued API key (`Authorization: Bearer ak_…`). Mint one at [`/dashboard/settings/api-keys`](https://app.sendero.travel/dashboard/settings/api-keys). Keys are tenant-scoped; the server derives both `tenantId` and the service-account `userId` from the key.\n\n## Dispatch shape\n\nEvery tool is callable via `POST /api/agent/dispatch` with `{ tool, args, tenantId }` in the body. The same tools are also exposed via MCP at `/api/mcp` for agent runtimes that prefer the MCP protocol.\n\n## Pricing\n\nEach call bills a per-tool nanopayment in micro-USDC via x402. See [`packages/tools/src/pricing.ts`](https://github.com/tcxcx/sendero/blob/main/packages/tools/src/pricing.ts) for the catalog. SaaS plan tiers grant a discount on the nanopayment rate.",
    "contact": {
      "name": "Sendero Developer Experience",
      "url": "https://docs.sendero.travel"
    }
  },
  "servers": [
    {
      "url": "https://www.sendero.travel",
      "description": "Production"
    },
    {
      "url": "https://preview.sendero.travel",
      "description": "Preview"
    }
  ],
  "components": {
    "securitySchemes": {
      "ClerkApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "ak_… (Clerk-issued)",
        "description": "Mint a production key at /dashboard/settings/api-keys. Sandbox keys are auto-issued on tenant creation and don't move real USDC."
      }
    },
    "schemas": {
      "SearchFlightsInput": {
        "type": "object",
        "required": ["origin", "destination", "departureDate"],
        "properties": {
          "origin": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "description": "IATA, e.g. SFO"
          },
          "destination": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "description": "IATA, e.g. LHR"
          },
          "departureDate": {
            "type": "string",
            "description": "YYYY-MM-DD"
          },
          "returnDate": {
            "type": "string",
            "description": "YYYY-MM-DD (optional)"
          },
          "passengers": {
            "type": "integer",
            "default": 1,
            "minimum": 1,
            "maximum": 9
          },
          "cabinClass": {
            "type": "string",
            "enum": ["economy", "premium_economy", "business", "first"],
            "default": "economy"
          },
          "privateFares": {
            "type": "object",
            "description": "Keyed by airline IATA code. Each entry is an array of credentials: { corporate_code, tour_code, tracking_reference, account_number }. See /guides/accessing-corporate-private-fares and /guides/adding-corporate-loyalty-programme-accounts.",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "corporate_code": {
                    "type": "string"
                  },
                  "tour_code": {
                    "type": "string"
                  },
                  "tracking_reference": {
                    "type": "string"
                  },
                  "account_number": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "leisureFareTypes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "student",
                "senior",
                "contract_bulk",
                "contract_bulk_child",
                "contract_bulk_infant_with_seat",
                "contract_bulk_infant_without_seat",
                "tour",
                "air_crew",
                "visiting_friends_and_family"
              ]
            }
          },
          "loyaltyProgrammeAccounts": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "object",
                "required": ["airlineIataCode", "accountNumber"],
                "properties": {
                  "airlineIataCode": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2
                  },
                  "accountNumber": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "airlineCreditIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "customerUserId": {
            "type": "string"
          },
          "linkSessionTraveler": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "BookFlightInput": {
        "type": "object",
        "required": ["offerId"],
        "properties": {
          "offerId": {
            "type": "string"
          },
          "services": {
            "type": "array",
            "description": "Ancillary service ids + quantities from list_flight_ancillaries.",
            "items": {
              "type": "object",
              "required": ["id"],
              "properties": {
                "id": {
                  "type": "string"
                },
                "quantity": {
                  "type": "integer",
                  "default": 1,
                  "minimum": 1,
                  "maximum": 9
                }
              }
            }
          },
          "additionalCustomerUserIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Additional icu_… ids to attach (personal assistant, team lead, etc.). The primary traveler is auto-resolved from the session."
          },
          "airlineCreditId": {
            "type": "string",
            "description": "Airline credit id (acd_…) to redeem toward this booking. Remainder paid from balance."
          }
        }
      },
      "SearchHotelsInput": {
        "type": "object",
        "required": ["location", "checkInDate", "checkOutDate"],
        "properties": {
          "location": {
            "type": "string",
            "description": "City, neighborhood, or airport code. Free-form text works."
          },
          "checkInDate": {
            "type": "string",
            "description": "YYYY-MM-DD"
          },
          "checkOutDate": {
            "type": "string",
            "description": "YYYY-MM-DD"
          },
          "guests": {
            "type": "integer",
            "default": 1,
            "minimum": 1,
            "maximum": 9
          },
          "rooms": {
            "type": "integer",
            "default": 1,
            "minimum": 1,
            "maximum": 9
          }
        }
      },
      "CheckTreasuryInput": {
        "type": "object",
        "properties": {}
      },
      "GatewayBalanceInput": {
        "type": "object",
        "properties": {}
      },
      "GatewayTransferInput": {
        "type": "object",
        "required": ["from", "to", "amount"],
        "properties": {
          "from": {
            "type": "string",
            "enum": [
              "Arc_Testnet",
              "Ethereum_Sepolia",
              "Base_Sepolia",
              "Avalanche_Fuji",
              "Optimism_Sepolia",
              "Arbitrum_Sepolia",
              "Polygon_Amoy"
            ],
            "description": "Source chain key"
          },
          "to": {
            "type": "string",
            "enum": [
              "Arc_Testnet",
              "Ethereum_Sepolia",
              "Base_Sepolia",
              "Avalanche_Fuji",
              "Optimism_Sepolia",
              "Arbitrum_Sepolia",
              "Polygon_Amoy"
            ],
            "description": "Destination chain key (usually Arc_Testnet)"
          },
          "amount": {
            "type": "string",
            "description": "Decimal USDC amount, e.g. \"5.00\""
          },
          "recipient": {
            "type": "string",
            "description": "0x-address on destination (defaults to treasury)"
          }
        }
      },
      "SwapTokensInput": {
        "type": "object",
        "required": ["fromToken", "toToken", "amount"],
        "properties": {
          "fromToken": {
            "type": "string",
            "enum": ["USDC", "EURC"]
          },
          "toToken": {
            "type": "string",
            "enum": ["USDC", "EURC"]
          },
          "amount": {
            "type": "string",
            "description": "Decimal amount, e.g. \"5.00\""
          }
        }
      },
      "SendTokensInput": {
        "type": "object",
        "required": ["to", "amount"],
        "properties": {
          "to": {
            "type": "string",
            "pattern": "^0x[a-fA-F0-9]{40}$"
          },
          "amount": {
            "type": "string"
          },
          "token": {
            "type": "string",
            "enum": ["USDC", "EURC"],
            "default": "USDC"
          }
        }
      },
      "BridgeToArcInput": {
        "type": "object",
        "required": ["fromChain", "amount"],
        "properties": {
          "fromChain": {
            "type": "string",
            "enum": [
              "Arbitrum",
              "Avalanche",
              "Base",
              "Codex",
              "Edge",
              "Ethereum",
              "HyperEVM",
              "Ink",
              "Linea",
              "Monad",
              "Morph",
              "Optimism",
              "Plume",
              "Polygon",
              "Sei",
              "Solana",
              "Sonic",
              "Unichain",
              "World_Chain",
              "XDC",
              "Arc_Testnet",
              "Arbitrum_Sepolia",
              "Avalanche_Fuji",
              "Base_Sepolia",
              "Codex_Testnet",
              "Edge_Testnet",
              "Ethereum_Sepolia",
              "HyperEVM_Testnet",
              "Ink_Testnet",
              "Linea_Sepolia",
              "Monad_Testnet",
              "Morph_Testnet",
              "Optimism_Sepolia",
              "Plume_Testnet",
              "Polygon_Amoy_Testnet",
              "Sei_Testnet",
              "Solana_Devnet",
              "Sonic_Testnet",
              "Unichain_Sepolia",
              "World_Chain_Sepolia",
              "XDC_Apothem"
            ]
          },
          "amount": {
            "type": "string"
          }
        }
      },
      "SwapAndBridgeInput": {
        "type": "object",
        "required": ["fromChain", "amount"],
        "properties": {
          "fromChain": {
            "type": "string",
            "enum": [
              "Arbitrum",
              "Avalanche",
              "Base",
              "Codex",
              "Edge",
              "Ethereum",
              "HyperEVM",
              "Ink",
              "Linea",
              "Monad",
              "Morph",
              "Optimism",
              "Plume",
              "Polygon",
              "Sei",
              "Solana",
              "Sonic",
              "Unichain",
              "World_Chain",
              "XDC",
              "Arc_Testnet",
              "Arbitrum_Sepolia",
              "Avalanche_Fuji",
              "Base_Sepolia",
              "Codex_Testnet",
              "Edge_Testnet",
              "Ethereum_Sepolia",
              "HyperEVM_Testnet",
              "Ink_Testnet",
              "Linea_Sepolia",
              "Monad_Testnet",
              "Morph_Testnet",
              "Optimism_Sepolia",
              "Plume_Testnet",
              "Polygon_Amoy_Testnet",
              "Sei_Testnet",
              "Solana_Devnet",
              "Sonic_Testnet",
              "Unichain_Sepolia",
              "World_Chain_Sepolia",
              "XDC_Apothem"
            ]
          },
          "amount": {
            "type": "string",
            "description": "USDC amount to bridge and swap, e.g. \"5.00\""
          },
          "targetToken": {
            "type": "string",
            "enum": ["USDC", "EURC"],
            "default": "EURC"
          }
        }
      },
      "SettleSplitInput": {
        "type": "object",
        "required": ["gross", "supplier"],
        "properties": {
          "gross": {
            "type": "string",
            "description": "Total booking amount in USDC (decimal string)."
          },
          "supplier": {
            "type": "string",
            "pattern": "^0x[a-fA-F0-9]{40}$"
          },
          "commissionBps": {
            "type": "integer",
            "default": 1000
          },
          "senderoFeeBps": {
            "type": "integer",
            "default": 100
          }
        }
      },
      "CheckPolicyInput": {
        "type": "object",
        "required": ["policyId", "offer"],
        "properties": {
          "policyId": {
            "type": "string",
            "enum": ["vale-corp-2026", "softtek-mx-2026", "default-corp"],
            "description": "Corporate travel policy identifier."
          },
          "offer": {
            "type": "object",
            "required": ["kind", "priceUsd"],
            "properties": {
              "kind": {
                "type": "string",
                "enum": ["flight", "hotel"]
              },
              "priceUsd": {
                "type": "number"
              },
              "carrierIata": {
                "type": "string"
              },
              "durationHours": {
                "type": "number"
              },
              "cabin": {
                "type": "string",
                "enum": ["economy", "premium_economy", "business", "first"]
              },
              "supplierId": {
                "type": "string"
              },
              "pricePerNightUsd": {
                "type": "number"
              }
            }
          }
        }
      },
      "QuoteFxInput": {
        "type": "object",
        "required": ["fromCurrency", "toCurrency", "amount"],
        "properties": {
          "fromCurrency": {
            "type": "string"
          },
          "toCurrency": {
            "type": "string",
            "enum": ["USDC", "USD", "EURC"]
          },
          "amount": {
            "type": "number"
          }
        }
      },
      "GiveFeedbackInput": {
        "type": "object",
        "required": ["subjectAgentId", "stars", "tag", "fromKind"],
        "properties": {
          "subjectAgentId": {
            "type": "string",
            "pattern": "^\\d+$"
          },
          "stars": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5
          },
          "tag": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "fromKind": {
            "type": "string",
            "enum": ["org", "user"]
          },
          "fromTenantId": {
            "type": "string"
          },
          "fromUserId": {
            "type": "string"
          },
          "tripId": {
            "type": "string"
          },
          "bookingId": {
            "type": "string"
          },
          "evidenceUri": {
            "type": "string"
          }
        }
      },
      "ReadReputationInput": {
        "type": "object",
        "properties": {
          "tenantId": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "agentId": {
            "type": "string",
            "pattern": "^\\d+$"
          },
          "recentLimit": {
            "type": "integer",
            "minimum": 0,
            "maximum": 50,
            "default": 10
          }
        }
      },
      "RequestValidationInput": {
        "type": "object",
        "required": ["subjectAgentId", "validatorAddress", "tag", "ownerWalletAddress"],
        "properties": {
          "subjectAgentId": {
            "type": "string",
            "pattern": "^\\d+$"
          },
          "validatorAddress": {
            "type": "string",
            "pattern": "^0x[a-fA-F0-9]{40}$"
          },
          "tag": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "requestUri": {
            "type": "string"
          },
          "ownerWalletAddress": {
            "type": "string",
            "pattern": "^0x[a-fA-F0-9]{40}$"
          },
          "seed": {
            "type": "string"
          }
        }
      },
      "SubmitValidationResponseInput": {
        "type": "object",
        "required": ["requestHash", "response", "tag", "validatorWalletAddress"],
        "properties": {
          "requestHash": {
            "type": "string",
            "pattern": "^0x[a-fA-F0-9]{64}$"
          },
          "response": {
            "type": "integer",
            "enum": [0, 100]
          },
          "tag": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "validatorWalletAddress": {
            "type": "string",
            "pattern": "^0x[a-fA-F0-9]{40}$"
          },
          "responseUri": {
            "type": "string"
          }
        }
      },
      "ReadValidationInput": {
        "type": "object",
        "required": ["requestHash"],
        "properties": {
          "requestHash": {
            "type": "string",
            "pattern": "^0x[a-fA-F0-9]{64}$"
          }
        }
      },
      "PrefundTripInput": {
        "type": "object",
        "required": ["budgetUsdc"],
        "properties": {
          "budgetUsdc": {
            "type": "string",
            "description": "Trip budget in decimal USDC."
          },
          "expiresInDays": {
            "type": "integer",
            "default": 30,
            "minimum": 1,
            "maximum": 365
          },
          "metadataCID": {
            "type": "string",
            "description": "Optional IPFS CID for trip intent JSON."
          },
          "metadataHash": {
            "type": "string",
            "description": "keccak256 of the trip intent."
          },
          "agentTokenId": {
            "type": "string",
            "description": "ERC-8004 agent token id."
          },
          "escrowAddress": {
            "type": "string",
            "description": "Override the default escrow address."
          },
          "linkOrigin": {
            "type": "string",
            "description": "Override the guest link origin."
          },
          "require2fa": {
            "type": "boolean",
            "default": false,
            "description": "Require a 6-digit OTP at claim time (out-of-band share)."
          },
          "guestEmail": {
            "type": "string",
            "description": "Email the guest directly when provided."
          },
          "guestName": {
            "type": "string",
            "description": "Display name for the email greeting."
          },
          "buyerName": {
            "type": "string",
            "description": "Buyer display name in subject + greeting."
          },
          "tripSummary": {
            "type": "string",
            "description": "Short route summary for email copy."
          }
        }
      },
      "GuestClaimLinkInput": {
        "type": "object",
        "required": ["guestLink", "guestWallet"],
        "properties": {
          "guestLink": {
            "type": "string"
          },
          "guestWallet": {
            "type": "string"
          },
          "chainId": {
            "type": "integer",
            "default": 5042002
          },
          "escrowAddress": {
            "type": "string"
          },
          "claimCode": {
            "type": "string",
            "description": "6-digit OTP if 2FA is on."
          },
          "codeNonce": {
            "type": "string",
            "description": "32-byte nonce returned by prefund_trip."
          }
        }
      },
      "ReserveBookingInput": {
        "type": "object",
        "required": ["tripId", "upperBoundUsdc"],
        "properties": {
          "tripId": {
            "type": "string"
          },
          "upperBoundUsdc": {
            "type": "string"
          },
          "bookingId": {
            "type": "string"
          },
          "escrowAddress": {
            "type": "string"
          }
        }
      },
      "CommitBookingInput": {
        "type": "object",
        "required": ["bookingId", "vendorAmountUsdc", "vendorAddress", "itineraryHash"],
        "properties": {
          "bookingId": {
            "type": "string"
          },
          "vendorAmountUsdc": {
            "type": "string"
          },
          "feeAmountUsdc": {
            "type": "string",
            "default": "0"
          },
          "vendorAddress": {
            "type": "string"
          },
          "itineraryHash": {
            "type": "string"
          },
          "itineraryCID": {
            "type": "string"
          },
          "escrowAddress": {
            "type": "string"
          }
        }
      },
      "ConfirmBookingInput": {
        "type": "object",
        "required": ["bookingId", "costMicroUsdc", "itineraryHash", "vendorAddress"],
        "properties": {
          "bookingId": {
            "type": "string"
          },
          "costMicroUsdc": {
            "type": "string",
            "description": "Supplier net rate in micro-USDC (decimal string)."
          },
          "markupBps": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000
          },
          "markupMicroUsdc": {
            "type": "string"
          },
          "override": {
            "type": "object",
            "properties": {
              "reason": {
                "type": "string",
                "enum": ["ceiling_acknowledged"]
              },
              "acknowledgedMicroUsdc": {
                "type": "string"
              }
            },
            "required": ["reason", "acknowledgedMicroUsdc"]
          },
          "itineraryHash": {
            "type": "string"
          },
          "itineraryCID": {
            "type": "string"
          },
          "vendorAddress": {
            "type": "string"
          },
          "escrowAddress": {
            "type": "string"
          }
        }
      },
      "ConfirmFlightInput": {
        "type": "object",
        "required": ["bookingId", "ticketOrderHash"],
        "properties": {
          "bookingId": {
            "type": "string"
          },
          "ticketOrderHash": {
            "type": "string"
          },
          "escrowAddress": {
            "type": "string"
          }
        }
      },
      "SettleBookingInput": {
        "type": "object",
        "required": ["bookingId"],
        "properties": {
          "bookingId": {
            "type": "string"
          },
          "escrowAddress": {
            "type": "string"
          }
        }
      },
      "CancelBookingInput": {
        "type": "object",
        "required": ["bookingId", "tripId", "reason"],
        "properties": {
          "bookingId": {
            "type": "string"
          },
          "tripId": {
            "type": "string"
          },
          "reason": {
            "type": "string",
            "enum": ["duffel_failed", "policy_reject", "buyer_cancel", "timeout"]
          },
          "escrowAddress": {
            "type": "string"
          }
        }
      },
      "GenerateBookingInvoiceInput": {
        "type": "object",
        "required": ["bookingId"],
        "properties": {
          "bookingId": {
            "type": "string",
            "description": "Escrow bookingId hex32 — matched via Booking.externalId."
          },
          "settleTxHash": {
            "type": "string",
            "description": "Tx hash of the settle_booking on-chain call."
          }
        }
      },
      "GetTenantPricingPolicyInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {}
      },
      "ActivateTenantPricingPolicyInput": {
        "type": "object",
        "required": ["markupConfig"],
        "properties": {
          "markupConfig": {
            "type": "object",
            "description": "Per-BookingKind markup config. v1 honors only { strategy: \"static\", bps: <int 0..10000> }."
          },
          "floorMicroUsdc": {
            "type": "string",
            "description": "Optional non-negative micro-USDC floor on tenant markup."
          },
          "ceilingMicroUsdc": {
            "type": "string",
            "description": "Optional non-negative micro-USDC ceiling on tenant markup. Null = none."
          },
          "senderoTakeBehavior": {
            "type": "string",
            "enum": ["add_to_customer", "deduct_from_markup"]
          }
        }
      },
      "LogAgentActionInput": {
        "type": "object",
        "required": ["tripId"],
        "properties": {
          "tripId": {
            "type": "string"
          },
          "actionType": {
            "type": "string",
            "enum": ["search", "chat", "hold", "commit", "other"],
            "default": "other"
          },
          "feeMicroUsdc": {
            "type": "string",
            "default": "0"
          },
          "escrowAddress": {
            "type": "string"
          }
        }
      },
      "GeocodeTripStopInput": {
        "type": "object",
        "required": ["address"],
        "properties": {
          "address": {
            "type": "string",
            "description": "Free-form address, place name, or stop text."
          },
          "languageCode": {
            "type": "string",
            "description": "BCP-47 language code.",
            "default": "en"
          },
          "regionCode": {
            "type": "string",
            "description": "Optional region code such as US or AR."
          }
        }
      },
      "TripWeatherBriefInput": {
        "type": "object",
        "required": ["latitude", "longitude"],
        "properties": {
          "latitude": {
            "type": "number"
          },
          "longitude": {
            "type": "number"
          },
          "unitsSystem": {
            "type": "string",
            "enum": ["METRIC", "IMPERIAL"],
            "default": "METRIC"
          },
          "languageCode": {
            "type": "string",
            "default": "en"
          }
        }
      },
      "AirQualityBriefInput": {
        "type": "object",
        "required": ["latitude", "longitude"],
        "properties": {
          "latitude": {
            "type": "number"
          },
          "longitude": {
            "type": "number"
          },
          "languageCode": {
            "type": "string",
            "default": "en"
          }
        }
      },
      "ValidateTravelAddressInput": {
        "type": "object",
        "required": ["addressLines"],
        "properties": {
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Address lines in mailing-address order."
          },
          "regionCode": {
            "type": "string"
          },
          "locality": {
            "type": "string"
          },
          "administrativeArea": {
            "type": "string"
          },
          "postalCode": {
            "type": "string"
          }
        }
      },
      "TimezoneBriefInput": {
        "type": "object",
        "required": ["latitude", "longitude"],
        "properties": {
          "latitude": {
            "type": "number"
          },
          "longitude": {
            "type": "number"
          },
          "timestamp": {
            "type": "integer",
            "description": "Unix seconds. Defaults to now."
          },
          "language": {
            "type": "string"
          }
        }
      },
      "ElevationRiskBriefInput": {
        "type": "object",
        "required": ["latitude", "longitude"],
        "properties": {
          "latitude": {
            "type": "number"
          },
          "longitude": {
            "type": "number"
          }
        }
      },
      "TravelSafetyAidInput": {
        "type": "object",
        "required": ["latitude", "longitude"],
        "properties": {
          "latitude": {
            "type": "number"
          },
          "longitude": {
            "type": "number"
          },
          "addressLines": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "regionCode": {
            "type": "string"
          },
          "travelerNotes": {
            "type": "string"
          },
          "languageCode": {
            "type": "string",
            "default": "en"
          }
        }
      },
      "RecommendRestaurantsInput": {
        "type": "object",
        "required": ["location"],
        "properties": {
          "location": {
            "type": "string",
            "description": "City, neighborhood, landmark, or free-form text."
          },
          "cuisine": {
            "type": "string",
            "description": "Optional cuisine hint (e.g. parrilla, sushi, vegan)."
          },
          "priceLevel": {
            "type": "string",
            "enum": ["inexpensive", "moderate", "expensive", "very_expensive"],
            "description": "Filter by price tier."
          },
          "partySize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 20
          },
          "limit": {
            "type": "integer",
            "default": 6,
            "minimum": 1,
            "maximum": 10
          },
          "languageCode": {
            "type": "string",
            "default": "en",
            "description": "BCP-47 language code steering returned text (e.g. en, es, pt)."
          }
        }
      },
      "ExportRouteMapInput": {
        "type": "object",
        "required": ["stops"],
        "properties": {
          "title": {
            "type": "string",
            "description": "Short itinerary title for the share card."
          },
          "stops": {
            "type": "array",
            "minItems": 2,
            "maxItems": 10,
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "address": {
                  "type": "string"
                },
                "latitude": {
                  "type": "number"
                },
                "longitude": {
                  "type": "number"
                },
                "placeId": {
                  "type": "string"
                }
              }
            },
            "description": "Ordered route stops. Each stop needs an address or both latitude and longitude."
          },
          "mode": {
            "type": "string",
            "enum": ["driving", "walking", "transit", "bicycling"],
            "default": "driving"
          },
          "channel": {
            "type": "string",
            "enum": ["whatsapp", "slack", "web", "email", "mcp"],
            "default": "web"
          },
          "notes": {
            "type": "string"
          },
          "includeStaticMap": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "RestaurantRouteCardInput": {
        "type": "object",
        "required": ["location"],
        "properties": {
          "location": {
            "type": "string",
            "description": "City, neighborhood, or landmark."
          },
          "cuisine": {
            "type": "string"
          },
          "priceLevel": {
            "type": "string",
            "enum": ["inexpensive", "moderate", "expensive", "very_expensive"]
          },
          "partySize": {
            "type": "integer",
            "minimum": 1,
            "maximum": 20
          },
          "limit": {
            "type": "integer",
            "default": 3,
            "minimum": 1,
            "maximum": 5
          },
          "languageCode": {
            "type": "string",
            "default": "en"
          },
          "fromLabel": {
            "type": "string",
            "description": "Label for the route start, e.g. \"Hotel Park Hyatt\"."
          },
          "fromAddress": {
            "type": "string"
          },
          "fromLatitude": {
            "type": "number"
          },
          "fromLongitude": {
            "type": "number"
          },
          "mode": {
            "type": "string",
            "enum": ["driving", "walking", "transit", "bicycling"],
            "default": "walking"
          },
          "occasion": {
            "type": "string"
          }
        }
      },
      "AirportTransferCoordinatorInput": {
        "type": "object",
        "required": ["airport", "destinationAddress"],
        "properties": {
          "airport": {
            "type": "string",
            "description": "IATA code, airport name, or free-form text for the arrival airport."
          },
          "airportLatitude": {
            "type": "number"
          },
          "airportLongitude": {
            "type": "number"
          },
          "destinationLabel": {
            "type": "string",
            "description": "Short label for the destination."
          },
          "destinationAddress": {
            "type": "string"
          },
          "regionCode": {
            "type": "string",
            "description": "CLDR region code, e.g. AR, US, FR."
          },
          "languageCode": {
            "type": "string",
            "default": "en"
          },
          "arrivalTimeIso": {
            "type": "string",
            "description": "ISO 8601 scheduled arrival."
          },
          "travelerCount": {
            "type": "integer",
            "minimum": 1,
            "maximum": 12,
            "default": 1
          },
          "mode": {
            "type": "string",
            "enum": ["driving", "transit", "walking"],
            "default": "driving"
          },
          "includeSafety": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "AirportArrivalPlaybookInput": {
        "type": "object",
        "required": ["airport", "destinationAddress"],
        "properties": {
          "airport": {
            "type": "string"
          },
          "airportLatitude": {
            "type": "number"
          },
          "airportLongitude": {
            "type": "number"
          },
          "destinationLabel": {
            "type": "string"
          },
          "destinationAddress": {
            "type": "string"
          },
          "regionCode": {
            "type": "string"
          },
          "languageCode": {
            "type": "string",
            "default": "en"
          },
          "arrivalTimeIso": {
            "type": "string"
          },
          "travelerName": {
            "type": "string"
          },
          "flightNumber": {
            "type": "string"
          },
          "pnr": {
            "type": "string"
          },
          "mode": {
            "type": "string",
            "enum": ["driving", "transit", "walking"],
            "default": "driving"
          }
        }
      },
      "TripCheckinReminderInput": {
        "type": "object",
        "required": ["origin", "departureDateTimeIso"],
        "properties": {
          "pnr": {
            "type": "string"
          },
          "flightNumber": {
            "type": "string"
          },
          "carrier": {
            "type": "string"
          },
          "origin": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3
          },
          "destination": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3
          },
          "departureDateTimeIso": {
            "type": "string",
            "description": "ISO 8601 departure time."
          },
          "airportLatitude": {
            "type": "number"
          },
          "airportLongitude": {
            "type": "number"
          },
          "stayLabel": {
            "type": "string"
          },
          "stayAddress": {
            "type": "string"
          },
          "stayLatitude": {
            "type": "number"
          },
          "stayLongitude": {
            "type": "number"
          },
          "transferMode": {
            "type": "string",
            "enum": ["driving", "transit"],
            "default": "driving"
          },
          "travelerName": {
            "type": "string"
          },
          "checkInWindowHours": {
            "type": "integer",
            "minimum": 1,
            "maximum": 72,
            "default": 24
          },
          "language": {
            "type": "string",
            "default": "en"
          }
        }
      },
      "TripDelayReplannerInput": {
        "type": "object",
        "required": ["originalLeg", "disruption", "rebookSearch"],
        "properties": {
          "originalLeg": {
            "type": "object",
            "required": ["origin", "destination", "scheduledDepartureIso"],
            "properties": {
              "pnr": {
                "type": "string"
              },
              "flightNumber": {
                "type": "string"
              },
              "carrier": {
                "type": "string"
              },
              "origin": {
                "type": "string",
                "minLength": 3,
                "maxLength": 3
              },
              "destination": {
                "type": "string",
                "minLength": 3,
                "maxLength": 3
              },
              "scheduledDepartureIso": {
                "type": "string"
              }
            }
          },
          "disruption": {
            "type": "object",
            "required": ["kind"],
            "properties": {
              "kind": {
                "type": "string",
                "enum": ["delay", "cancellation", "missed_connection", "weather", "other"]
              },
              "earliestUsableDepartureIso": {
                "type": "string"
              },
              "reason": {
                "type": "string"
              }
            }
          },
          "rebookSearch": {
            "type": "object",
            "required": ["departureDate"],
            "properties": {
              "departureDate": {
                "type": "string",
                "description": "YYYY-MM-DD"
              },
              "passengers": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9,
                "default": 1
              },
              "cabinClass": {
                "type": "string",
                "enum": ["economy", "premium_economy", "business", "first"],
                "default": "economy"
              }
            }
          },
          "needsHotelFallback": {
            "type": "boolean",
            "default": false
          },
          "stayLocation": {
            "type": "string"
          },
          "stayCheckInDate": {
            "type": "string"
          },
          "stayCheckOutDate": {
            "type": "string"
          },
          "travelerLabel": {
            "type": "string"
          },
          "notifyChannels": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["whatsapp", "slack", "email"]
            },
            "default": ["whatsapp", "slack"]
          },
          "transferMode": {
            "type": "string",
            "enum": ["driving", "transit"],
            "default": "driving"
          }
        }
      },
      "EnsureFlightCustomerInput": {
        "type": "object",
        "properties": {
          "clerkUserId": {
            "type": "string",
            "description": "Traveler Clerk user id."
          },
          "tenantId": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "givenName": {
            "type": "string"
          },
          "familyName": {
            "type": "string"
          },
          "phoneNumber": {
            "type": "string",
            "description": "E.164 phone number."
          },
          "preferredLanguage": {
            "type": "string",
            "description": "BCP-47 language tag for Travel Support Assistant replies."
          }
        }
      },
      "ListFlightAncillariesInput": {
        "type": "object",
        "required": ["offerId"],
        "properties": {
          "offerId": {
            "type": "string",
            "description": "Flight offer id (off_…)."
          },
          "maxSeats": {
            "type": "integer",
            "default": 24,
            "minimum": 1,
            "maximum": 48
          }
        }
      },
      "FindAirportsNearbyInput": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Free-form place name, IATA code, or airline."
          },
          "latitude": {
            "type": "number"
          },
          "longitude": {
            "type": "number"
          },
          "radiusMeters": {
            "type": "integer",
            "minimum": 1000,
            "maximum": 500000,
            "default": 100000
          },
          "maxResults": {
            "type": "integer",
            "minimum": 1,
            "maximum": 20,
            "default": 8
          }
        }
      },
      "DisplayOfferConditionsInput": {
        "type": "object",
        "required": ["offerId"],
        "properties": {
          "offerId": {
            "type": "string"
          }
        }
      },
      "QuoteStayInput": {
        "type": "object",
        "required": ["rateId"],
        "properties": {
          "rateId": {
            "type": "string"
          }
        }
      },
      "BookStayInput": {
        "type": "object",
        "required": ["quoteId", "email", "guests"],
        "properties": {
          "quoteId": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phoneNumber": {
            "type": "string"
          },
          "guests": {
            "type": "array",
            "minItems": 1,
            "maxItems": 9,
            "items": {
              "type": "object",
              "required": ["givenName", "familyName"],
              "properties": {
                "givenName": {
                  "type": "string"
                },
                "familyName": {
                  "type": "string"
                },
                "bornOn": {
                  "type": "string",
                  "description": "ISO date"
                },
                "customerUserId": {
                  "type": "string"
                }
              }
            }
          },
          "loyaltyProgrammeAccountNumber": {
            "type": "string"
          },
          "accommodationSpecialRequests": {
            "type": "string",
            "maxLength": 1000
          },
          "additionalCustomerUserIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CancelOrderQuoteInput": {
        "type": "object",
        "required": ["orderId"],
        "properties": {
          "orderId": {
            "type": "string"
          }
        }
      },
      "ConfirmCancelOrderInput": {
        "type": "object",
        "required": ["cancellationId"],
        "properties": {
          "cancellationId": {
            "type": "string"
          }
        }
      },
      "RequestOrderChangeInput": {
        "type": "object",
        "required": ["orderId", "slices"],
        "properties": {
          "orderId": {
            "type": "string"
          },
          "slices": {
            "type": "object",
            "required": ["add", "remove"],
            "properties": {
              "add": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": ["origin", "destination", "departure_date"],
                  "properties": {
                    "origin": {
                      "type": "string"
                    },
                    "destination": {
                      "type": "string"
                    },
                    "departure_date": {
                      "type": "string"
                    },
                    "cabin_class": {
                      "type": "string",
                      "enum": ["economy", "premium_economy", "business", "first"]
                    }
                  }
                }
              },
              "remove": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": ["slice_id"],
                  "properties": {
                    "slice_id": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "SelectOrderChangeOfferInput": {
        "type": "object",
        "required": ["offerId"],
        "properties": {
          "offerId": {
            "type": "string"
          }
        }
      },
      "ConfirmOrderChangeInput": {
        "type": "object",
        "required": ["changeId", "payment"],
        "properties": {
          "changeId": {
            "type": "string"
          },
          "payment": {
            "type": "object",
            "required": ["type", "amount", "currency"],
            "properties": {
              "type": {
                "type": "string",
                "enum": ["balance", "arc", "card"]
              },
              "amount": {
                "type": "string"
              },
              "currency": {
                "type": "string"
              }
            }
          }
        }
      },
      "ListAirlineCreditsInput": {
        "type": "object",
        "properties": {
          "clerkUserId": {
            "type": "string"
          },
          "tenantId": {
            "type": "string"
          },
          "customerUserId": {
            "type": "string"
          },
          "limit": {
            "type": "integer",
            "default": 20,
            "minimum": 1,
            "maximum": 50
          }
        }
      },
      "ManageStaysNegotiatedRateInput": {
        "type": "object",
        "required": ["action"],
        "properties": {
          "action": {
            "type": "string",
            "enum": ["create", "update", "delete"]
          },
          "negotiatedRateId": {
            "type": "string",
            "description": "Required for update + delete (nre_…)."
          },
          "displayName": {
            "type": "string"
          },
          "rateAccessCode": {
            "type": "string"
          },
          "accommodationIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 500
          }
        }
      },
      "FaucetDripInput": {
        "type": "object",
        "required": ["address"],
        "properties": {
          "address": {
            "type": "string",
            "description": "Destination EOA / MSCA / contract address."
          },
          "blockchain": {
            "type": "string",
            "enum": ["ARC-TESTNET", "ETH-SEPOLIA", "AVAX-FUJI", "MATIC-AMOY"],
            "default": "ARC-TESTNET"
          },
          "token": {
            "type": "string",
            "enum": ["USDC", "EURC"],
            "default": "USDC"
          }
        }
      },
      "ScanDocumentInput": {
        "type": "object",
        "required": ["kind"],
        "properties": {
          "kind": {
            "type": "string",
            "enum": ["invoice", "receipt", "boarding_pass", "id_document"]
          },
          "documentUrl": {
            "type": "string",
            "format": "uri"
          },
          "data": {
            "type": "string"
          },
          "mediaType": {
            "type": "string"
          },
          "companyName": {
            "type": "string"
          }
        }
      },
      "CheckTravelEligibilityInput": {
        "type": "object",
        "required": ["travelerUserId", "originIso3", "destinationIso3", "departureDate", "purpose"],
        "properties": {
          "travelerUserId": {
            "type": "string"
          },
          "originIso3": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3
          },
          "destinationIso3": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3
          },
          "departureDate": {
            "type": "string"
          },
          "returnDate": {
            "type": "string"
          },
          "purpose": {
            "type": "string",
            "enum": ["business", "leisure", "transit", "study", "medical"]
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Search"
    },
    {
      "name": "Bookings"
    },
    {
      "name": "Treasury"
    },
    {
      "name": "Settlement"
    },
    {
      "name": "Utilities"
    },
    {
      "name": "Trip assistance"
    },
    {
      "name": "Compliance"
    },
    {
      "name": "Documents"
    }
  ],
  "paths": {
    "/api/agent/dispatch#search_flights": {
      "post": {
        "operationId": "search_flights",
        "summary": "Search flights between two airports.",
        "description": "Search flights between two airports. Requires IATA codes and a departure date (YYYY-MM-DD). Supports corporate private fares + corporate loyalty programmes via `privateFares`, leisure private fares via per-passenger `leisureFareTypes`, per-passenger loyalty accounts, and airline-credit matching via `airlineCreditIds` or `linkSessionTraveler`.",
        "tags": ["Search"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["search_flights"],
                    "description": "Must be exactly `search_flights` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/SearchFlightsInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#book_flight": {
      "post": {
        "operationId": "book_flight",
        "summary": "Book a flight for the signed-in user: ensures the traveler identity exists with the supplier, creates a hold order (with any ancillary se…",
        "description": "Book a flight for the signed-in user: ensures the traveler identity exists with the supplier, creates a hold order (with any ancillary services attached), and pays from the pre-funded balance — optionally splitting payment with a traveler airline credit. Returns the PNR + order id. The traveler automatically gets Travel Support Assistant access through their linked identity. Passenger identity comes from the signed-in Clerk session — do not ask the user for name, email, or phone.",
        "tags": ["Bookings"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["book_flight"],
                    "description": "Must be exactly `book_flight` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/BookFlightInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#search_hotels": {
      "post": {
        "operationId": "search_hotels",
        "summary": "Search hotels in a city for given dates.",
        "description": "Search hotels in a city for given dates. Returns up to 6 accommodations with real photos, star rating, review score, cheapest rate, and cancellation policy. Use when the user asks for lodging.",
        "tags": ["Search"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["search_hotels"],
                    "description": "Must be exactly `search_hotels` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/SearchHotelsInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#check_treasury": {
      "post": {
        "operationId": "check_treasury",
        "summary": "Check Circle treasury USDC/EURC balance on Arc.",
        "description": "Check Circle treasury USDC/EURC balance on Arc. Use when the user asks about funds.",
        "tags": ["Treasury"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["check_treasury"],
                    "description": "Must be exactly `check_treasury` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/CheckTreasuryInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#gateway_balance": {
      "post": {
        "operationId": "gateway_balance",
        "summary": "Return the treasury USDC unified balance across every Gateway-supported testnet (Arc, Ethereum Sepolia, Base Sepolia, Avalanche Fuji, etc.).",
        "description": "Return the treasury USDC unified balance across every Gateway-supported testnet (Arc, Ethereum Sepolia, Base Sepolia, Avalanche Fuji, etc.). Fast — queries Circle Gateway API.",
        "tags": ["Treasury"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["gateway_balance"],
                    "description": "Must be exactly `gateway_balance` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/GatewayBalanceInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#gateway_transfer": {
      "post": {
        "operationId": "gateway_transfer",
        "summary": "Pull USDC from any Gateway-supported chain and mint it on Arc Testnet (or any other Gateway chain) in sub-500ms.",
        "description": "Pull USDC from any Gateway-supported chain and mint it on Arc Testnet (or any other Gateway chain) in sub-500ms. Server signs the burn intent, Circle attests, destination mints. Use when Arc liquidity is short.",
        "tags": ["Treasury"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["gateway_transfer"],
                    "description": "Must be exactly `gateway_transfer` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/GatewayTransferInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#swap_tokens": {
      "post": {
        "operationId": "swap_tokens",
        "summary": "Rebalance the Sendero corporate treasury on Arc Testnet by swapping USDC ↔ EURC via Circle App Kit.",
        "description": "Rebalance the Sendero corporate treasury on Arc Testnet by swapping USDC ↔ EURC via Circle App Kit. Use when the treasury lacks the right token to pay for a booking, or the user explicitly asks to swap. Returns tx hashes.",
        "tags": ["Treasury"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["swap_tokens"],
                    "description": "Must be exactly `swap_tokens` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/SwapTokensInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#send_tokens": {
      "post": {
        "operationId": "send_tokens",
        "summary": "Transfer USDC or EURC from the Sendero corporate treasury to any Arc Testnet address.",
        "description": "Transfer USDC or EURC from the Sendero corporate treasury to any Arc Testnet address. Use when rebalancing or topping up the user wallet.",
        "tags": ["Treasury"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["send_tokens"],
                    "description": "Must be exactly `send_tokens` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/SendTokensInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#bridge_to_arc": {
      "post": {
        "operationId": "bridge_to_arc",
        "summary": "Bridge USDC from any App Kit–supported chain INTO Arc Testnet via Circle CCTP.",
        "description": "Bridge USDC from any App Kit–supported chain INTO Arc Testnet via Circle CCTP. Use when Arc treasury liquidity is low. Supports EVM chains (Ethereum, Base, Polygon, Avalanche, Arbitrum, Optimism, Unichain, Linea, etc.) plus Solana — mainnet and testnet variants (see BRIDGE_CHAINS for the full list).",
        "tags": ["Treasury"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["bridge_to_arc"],
                    "description": "Must be exactly `bridge_to_arc` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/BridgeToArcInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#swap_and_bridge": {
      "post": {
        "operationId": "swap_and_bridge",
        "summary": "Composed workflow: CCTP-bridge USDC from a source chain INTO Arc Testnet, then swap to EURC on Arc.",
        "description": "Composed workflow: CCTP-bridge USDC from a source chain INTO Arc Testnet, then swap to EURC on Arc. Use when a booking needs EURC but treasury only has USDC on another chain. Returns both step receipts.",
        "tags": ["Treasury"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["swap_and_bridge"],
                    "description": "Must be exactly `swap_and_bridge` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/SwapAndBridgeInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#settle_split": {
      "post": {
        "operationId": "settle_split",
        "summary": "Execute a canonical commission fan-out on Arc Testnet in a single batch: gross splits atomically into supplier net + agency commission + …",
        "description": "Execute a canonical commission fan-out on Arc Testnet in a single batch: gross splits atomically into supplier net + agency commission + Sendero rail + validator tip. Pass gross + supplier address; defaults fill other parties.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["settle_split"],
                    "description": "Must be exactly `settle_split` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/SettleSplitInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#check_policy": {
      "post": {
        "operationId": "check_policy",
        "summary": "Check a travel offer against a corporate travel policy.",
        "description": "Check a travel offer against a corporate travel policy. Returns { allowed, reasons[], warnings[] }. Cheap — call before every book.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["check_policy"],
                    "description": "Must be exactly `check_policy` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/CheckPolicyInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#quote_fx": {
      "post": {
        "operationId": "quote_fx",
        "summary": "FX quote for cross-currency settlements.",
        "description": "FX quote for cross-currency settlements. Pass local-currency price, get the USDC (or EURC) equivalent. Use before any off-USD booking.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["quote_fx"],
                    "description": "Must be exactly `quote_fx` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/QuoteFxInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#give_feedback": {
      "post": {
        "operationId": "give_feedback",
        "summary": "Record a 1-5 star rating for a counterparty on the ERC-8004 ReputationRegistry on Arc.",
        "description": "Record a 1-5 star rating for a counterparty on the ERC-8004 ReputationRegistry on Arc. Cross-rating: the rater's own DCW signs (not Sendero treasury), so the on-chain trust graph is a true peer graph. Self-rating is rejected. Score mapping: stars × 20.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["give_feedback"],
                    "description": "Must be exactly `give_feedback` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/GiveFeedbackInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#read_reputation": {
      "post": {
        "operationId": "read_reputation",
        "summary": "Read aggregated ERC-8004 reputation for a Sendero org, user, or any on-chain agent NFT.",
        "description": "Read aggregated ERC-8004 reputation for a Sendero org, user, or any on-chain agent NFT. Cache-first (~50ms) with chain RPC fallback for external agents. Returns mean stars 0-5, feedback count, validator count, validation count, and the most-recent feedback rows.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["read_reputation"],
                    "description": "Must be exactly `read_reputation` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ReadReputationInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#request_validation": {
      "post": {
        "operationId": "request_validation",
        "summary": "Open an ERC-8004 ValidationRegistry request asking a specific validator address to attest something (KYC, KYB, suitability) about an agen…",
        "description": "Open an ERC-8004 ValidationRegistry request asking a specific validator address to attest something (KYC, KYB, suitability) about an agent NFT. Returns the requestHash; pair with submit_validation_response.",
        "tags": ["Compliance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["request_validation"],
                    "description": "Must be exactly `request_validation` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/RequestValidationInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#submit_validation_response": {
      "post": {
        "operationId": "submit_validation_response",
        "summary": "Validator-side response to a pending ERC-8004 ValidationRegistry request.",
        "description": "Validator-side response to a pending ERC-8004 ValidationRegistry request. response=100 means passed, 0 means failed. Updates the off-chain ValidationCheck row.",
        "tags": ["Compliance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["submit_validation_response"],
                    "description": "Must be exactly `submit_validation_response` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/SubmitValidationResponseInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#read_validation": {
      "post": {
        "operationId": "read_validation",
        "summary": "Read the verdict of an ERC-8004 ValidationRegistry check by its requestHash.",
        "description": "Read the verdict of an ERC-8004 ValidationRegistry check by its requestHash. Returns 100=passed, 0=failed, null=pending.",
        "tags": ["Compliance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["read_validation"],
                    "description": "Must be exactly `read_validation` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ReadValidationInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#prefund_trip": {
      "post": {
        "operationId": "prefund_trip",
        "summary": "Corporate buyer path: fund a trip budget in USDC on SenderoGuestEscrow and return a WhatsApp-shareable guest link (Peanut-style — the cla…",
        "description": "Corporate buyer path: fund a trip budget in USDC on SenderoGuestEscrow and return a WhatsApp-shareable guest link (Peanut-style — the claim key lives in the URL fragment). Returns the on-chain calls (approve + createTrip) to submit via Circle Modular Wallets plus the link to DM the traveler. Front-running safe because the claim signature binds to the guest wallet at claim time.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["prefund_trip"],
                    "description": "Must be exactly `prefund_trip` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/PrefundTripInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#guest_claim_link": {
      "post": {
        "operationId": "guest_claim_link",
        "summary": "Guest path: parse a Sendero guest link, sign the EIP-191 claim message with the embedded private key, and return the calldata the guest M…",
        "description": "Guest path: parse a Sendero guest link, sign the EIP-191 claim message with the embedded private key, and return the calldata the guest MSCA should submit to claim the trip. After this completes, the booking agent can call reserve_booking / commit_booking against the claimed trip.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["guest_claim_link"],
                    "description": "Must be exactly `guest_claim_link` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/GuestClaimLinkInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#reserve_booking": {
      "post": {
        "operationId": "reserve_booking",
        "summary": "Agent path: reserve an upper-bound USDC amount from a claimed trip for a specific booking attempt.",
        "description": "Agent path: reserve an upper-bound USDC amount from a claimed trip for a specific booking attempt. Called before search_flights → book_flight so escrow can block any conflicting draws while Duffel is held. Returns the on-chain call to submit and the bookingId to thread through commit_booking + confirm_flight.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["reserve_booking"],
                    "description": "Must be exactly `reserve_booking` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ReserveBookingInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#commit_booking": {
      "post": {
        "operationId": "commit_booking",
        "summary": "Agent path: commit the actual vendor amount for a reserved booking.",
        "description": "Agent path: commit the actual vendor amount for a reserved booking. Releases the slack back to the trip budget. Use after Duffel returns a priced offer and before the booking is ticketed. Pair with confirm_flight once the order hash is known and settle_booking after the PNR is ticketed.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["commit_booking"],
                    "description": "Must be exactly `commit_booking` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/CommitBookingInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#confirm_booking": {
      "post": {
        "operationId": "confirm_booking",
        "summary": "Agent path: pin tenant pricing policy snapshot, compute markup breakdown (supplier cost + agency markup + Sendero take), persist the brea…",
        "description": "Agent path: pin tenant pricing policy snapshot, compute markup breakdown (supplier cost + agency markup + Sendero take), persist the breakdown to the Booking row, and encode the commitBookingV2 userOp. Three-recipient release: vendor + agency + operator. Operator submits the userOp; this tool only encodes. Charges the per-call x402 fee + the Sendero take in one MeterEvent.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["confirm_booking"],
                    "description": "Must be exactly `confirm_booking` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ConfirmBookingInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#confirm_flight": {
      "post": {
        "operationId": "confirm_flight",
        "summary": "Agent path: submit the on-chain flight-confirmation call after the supplier issues a ticket.",
        "description": "Agent path: submit the on-chain flight-confirmation call after the supplier issues a ticket. Pairs a bookingId with the canonical supplier order hash so auditors can reconstruct the escrow → ticket mapping. Returns an encoded userOp call; caller submits via operator MSCA.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["confirm_flight"],
                    "description": "Must be exactly `confirm_flight` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ConfirmFlightInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#settle_booking": {
      "post": {
        "operationId": "settle_booking",
        "summary": "Agent path: release escrow for a confirmed booking.",
        "description": "Agent path: release escrow for a confirmed booking. Transfers vendorAmount to the vendor and feeAmount to the operator in one tx. Caller submits via operator MSCA userOp. Should run AFTER confirm_flight and only when Duffel status=ticketed.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["settle_booking"],
                    "description": "Must be exactly `settle_booking` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/SettleBookingInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#cancel_booking": {
      "post": {
        "operationId": "cancel_booking",
        "summary": "Agent path: cancel a reserved/committed booking and refund the remaining escrow to the buyer.",
        "description": "Agent path: cancel a reserved/committed booking and refund the remaining escrow to the buyer. Emits two on-chain calls (refundBooking + sweepUnspent) to submit together via operator MSCA executeBatch.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["cancel_booking"],
                    "description": "Must be exactly `cancel_booking` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/CancelBookingInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#generate_booking_invoice": {
      "post": {
        "operationId": "generate_booking_invoice",
        "summary": "Issue a booking invoice after settle_booking.",
        "description": "Issue a booking invoice after settle_booking. Creates Invoice + LineItem(s) + Payment rows, renders PDF to Vercel Blob, signs public token, emails the traveler. Itemized vs single-line driven by Booking.metadata.invoiceItemization (frozen at confirm time). Idempotent on the booking (unique FK).",
        "tags": ["Documents"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["generate_booking_invoice"],
                    "description": "Must be exactly `generate_booking_invoice` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/GenerateBookingInvoiceInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#get_tenant_pricing_policy": {
      "post": {
        "operationId": "get_tenant_pricing_policy",
        "summary": "Read the active markup policy for the current tenant.",
        "description": "Read the active markup policy for the current tenant. Returns the policy status (active / inactive / partial / sandbox_seed / not_initialized), missing booking kinds, floor/ceiling, sendero take behavior, and a deep-link to the activation page. The tenant is resolved from the API key — the LLM never passes a tenantId.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["get_tenant_pricing_policy"],
                    "description": "Must be exactly `get_tenant_pricing_policy` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/GetTenantPricingPolicyInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#activate_tenant_pricing_policy": {
      "post": {
        "operationId": "activate_tenant_pricing_policy",
        "summary": "Activate a new TenantPricingPolicy version for the current tenant.",
        "description": "Activate a new TenantPricingPolicy version for the current tenant. Admin-only: requires an operator/admin API key (scope = \"*\", effectiveKeyType = \"production\"). Sandbox keys are rejected. Runs the treasury preflight before flipping `activated=true` so the booking pipeline can settle. Returns the new policyId + monotonic version. Inserts inside a transaction to defeat concurrent-write races on the (tenantId, version) UNIQUE.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["activate_tenant_pricing_policy"],
                    "description": "Must be exactly `activate_tenant_pricing_policy` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ActivateTenantPricingPolicyInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#log_agent_action": {
      "post": {
        "operationId": "log_agent_action",
        "summary": "Emit an on-chain breadcrumb for an agent action against a claimed trip.",
        "description": "Emit an on-chain breadcrumb for an agent action against a claimed trip. Used for x402 trace + ERC-8004 reputation aggregation. Optional — not required for a valid booking flow.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["log_agent_action"],
                    "description": "Must be exactly `log_agent_action` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/LogAgentActionInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#geocode_trip_stop": {
      "post": {
        "operationId": "geocode_trip_stop",
        "summary": "Normalize an itinerary stop into a canonical address and coordinates.",
        "description": "Normalize an itinerary stop into a canonical address and coordinates. Use before routing, weather, timezone, or safety checks when the user gives a city, hotel, airport, embassy, clinic, or free-form stop text.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["geocode_trip_stop"],
                    "description": "Must be exactly `geocode_trip_stop` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/GeocodeTripStopInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#trip_weather_brief": {
      "post": {
        "operationId": "trip_weather_brief",
        "summary": "Get the current weather conditions for a location.",
        "description": "Get the current weather conditions for a location. Use for departure readiness, disruption checks, and travel safety guidance.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["trip_weather_brief"],
                    "description": "Must be exactly `trip_weather_brief` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/TripWeatherBriefInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#air_quality_brief": {
      "post": {
        "operationId": "air_quality_brief",
        "summary": "Get current air quality for a location, including AQI and health recommendations.",
        "description": "Get current air quality for a location, including AQI and health recommendations. Use for respiratory-risk and outdoor-activity guidance.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["air_quality_brief"],
                    "description": "Must be exactly `air_quality_brief` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/AirQualityBriefInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#validate_travel_address": {
      "post": {
        "operationId": "validate_travel_address",
        "summary": "Validate, standardize, and geocode a travel-critical address such as a hotel, pickup, embassy, clinic, or delivery point.",
        "description": "Validate, standardize, and geocode a travel-critical address such as a hotel, pickup, embassy, clinic, or delivery point.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["validate_travel_address"],
                    "description": "Must be exactly `validate_travel_address` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ValidateTravelAddressInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#timezone_brief": {
      "post": {
        "operationId": "timezone_brief",
        "summary": "Return time zone and local-time context for a location.",
        "description": "Return time zone and local-time context for a location. Use for arrival planning, meeting safety, and transfer timing.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["timezone_brief"],
                    "description": "Must be exactly `timezone_brief` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/TimezoneBriefInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#elevation_risk_brief": {
      "post": {
        "operationId": "elevation_risk_brief",
        "summary": "Get elevation for a location and classify altitude sensitivity risk.",
        "description": "Get elevation for a location and classify altitude sensitivity risk. Use for mountain destinations, hiking, and high-altitude arrival warnings.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["elevation_risk_brief"],
                    "description": "Must be exactly `elevation_risk_brief` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ElevationRiskBriefInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#travel_safety_aid": {
      "post": {
        "operationId": "travel_safety_aid",
        "summary": "Combine weather, air quality, timezone, elevation, street-level arrival preview, and optional address validation into a single travel saf…",
        "description": "Combine weather, air quality, timezone, elevation, street-level arrival preview, and optional address validation into a single travel safety brief.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["travel_safety_aid"],
                    "description": "Must be exactly `travel_safety_aid` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/TravelSafetyAidInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#recommend_restaurants": {
      "post": {
        "operationId": "recommend_restaurants",
        "summary": "Suggest restaurants for the traveler during a trip.",
        "description": "Suggest restaurants for the traveler during a trip. Wraps Google Places API (New) text search, filtered to restaurants. Use when the traveler asks for food recommendations, a dinner spot, or a specific cuisine in a city/neighborhood. Returns up to 10 places with name, address, phone, website, rating, price level, and open-now status.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["recommend_restaurants"],
                    "description": "Must be exactly `recommend_restaurants` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/RecommendRestaurantsInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#export_route_map": {
      "post": {
        "operationId": "export_route_map",
        "summary": "Export a Sendero route or itinerary into shareable Google Maps and Apple Maps links, plus a static map preview card for WhatsApp, Slack, …",
        "description": "Export a Sendero route or itinerary into shareable Google Maps and Apple Maps links, plus a static map preview card for WhatsApp, Slack, or web chat. Use after picking a restaurant, hotel, airport transfer, or multi-stop itinerary.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["export_route_map"],
                    "description": "Must be exactly `export_route_map` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ExportRouteMapInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#restaurant_route_card": {
      "post": {
        "operationId": "restaurant_route_card",
        "summary": "Produce a polished concierge recommendation: a shortlisted restaurant with a route preview from the traveler's current location (hotel, o…",
        "description": "Produce a polished concierge recommendation: a shortlisted restaurant with a route preview from the traveler's current location (hotel, office, airport). Composes recommend_restaurants + export_route_map into one canonical share card for web, WhatsApp, and Slack.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["restaurant_route_card"],
                    "description": "Must be exactly `restaurant_route_card` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/RestaurantRouteCardInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#airport_transfer_coordinator": {
      "post": {
        "operationId": "airport_transfer_coordinator",
        "summary": "Turn arrival details into a pickup plan with meeting point, primary transport, backup options, and a ready route from airport to destinat…",
        "description": "Turn arrival details into a pickup plan with meeting point, primary transport, backup options, and a ready route from airport to destination. Composes geocode_trip_stop, validate_travel_address, export_route_map, and travel_safety_aid. Use for hotel pickups, embassy visits, or any post-landing ground leg.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["airport_transfer_coordinator"],
                    "description": "Must be exactly `airport_transfer_coordinator` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/AirportTransferCoordinatorInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#airport_arrival_playbook": {
      "post": {
        "operationId": "airport_arrival_playbook",
        "summary": "Deliver a one-screen arrival briefing: 5-step playbook from deplane to check-in, primary + backup transport, local timezone, destination …",
        "description": "Deliver a one-screen arrival briefing: 5-step playbook from deplane to check-in, primary + backup transport, local timezone, destination risk, and a ready route. Composes airport_transfer_coordinator + timezone_brief. Use right before or during landing.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["airport_arrival_playbook"],
                    "description": "Must be exactly `airport_arrival_playbook` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/AirportArrivalPlaybookInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#trip_checkin_reminder": {
      "post": {
        "operationId": "trip_checkin_reminder",
        "summary": "Generate the canonical trip check-in nudge: check-in window, airport transit note, leave-by time, and one obvious next action.",
        "description": "Generate the canonical trip check-in nudge: check-in window, airport transit note, leave-by time, and one obvious next action. Composes timezone_brief and (when stay coordinates are provided) export_route_map. Returns a WhatsApp/Slack-ready share shape. This is the tool the sendero.check_in_reminder workflow calls.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["trip_checkin_reminder"],
                    "description": "Must be exactly `trip_checkin_reminder` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/TripCheckinReminderInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#trip_delay_replanner": {
      "post": {
        "operationId": "trip_delay_replanner",
        "summary": "Rebuild the next safe plan after a delay, cancellation, or missed connection.",
        "description": "Rebuild the next safe plan after a delay, cancellation, or missed connection. Searches replacement flights, optionally searches overnight hotels, and exports the airport→hotel route when an overnight is forced. Returns a canonical rebook plan plus a share shape ready for WhatsApp, Slack, or the sendero.book_flight workflow.",
        "tags": ["Trip assistance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["trip_delay_replanner"],
                    "description": "Must be exactly `trip_delay_replanner` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/TripDelayReplannerInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#ensure_flight_customer": {
      "post": {
        "operationId": "ensure_flight_customer",
        "summary": "Keep the traveler in sync with the supplier identity layer.",
        "description": "Keep the traveler in sync with the supplier identity layer. Idempotent: reuses an existing traveler id on email match, creates one otherwise, and lazily ensures the tenant group. Call this before book_flight or any operation that should unlock Travel Support Assistant access for the end user.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["ensure_flight_customer"],
                    "description": "Must be exactly `ensure_flight_customer` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/EnsureFlightCustomerInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#list_flight_ancillaries": {
      "post": {
        "operationId": "list_flight_ancillaries",
        "summary": "Return the bags, cancel-for-any-reason, and seat options available on a flight offer.",
        "description": "Return the bags, cancel-for-any-reason, and seat options available on a flight offer. Use right after search_flights to show the traveler which extras the airline will sell. The canonical service ids can be passed straight into book_flight as `services: [{ id, quantity }]`.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["list_flight_ancillaries"],
                    "description": "Must be exactly `list_flight_ancillaries` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ListFlightAncillariesInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#find_airports_nearby": {
      "post": {
        "operationId": "find_airports_nearby",
        "summary": "Find Duffel-bookable airports (and metropolitan areas) near a lat/lng or matching a free-form query.",
        "description": "Find Duffel-bookable airports (and metropolitan areas) near a lat/lng or matching a free-form query. Use when the traveler gives a city that has no direct airport (e.g. Lagos PT → Faro / Portimão) or when you need to expand a search across nearby IATA codes.",
        "tags": ["Search"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["find_airports_nearby"],
                    "description": "Must be exactly `find_airports_nearby` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/FindAirportsNearbyInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#display_offer_conditions": {
      "post": {
        "operationId": "display_offer_conditions",
        "summary": "Return the change/refund conditions for a Duffel offer in a canonical shape (free / penalty / not allowed / unknown / allowed-unknown-fee).",
        "description": "Return the change/refund conditions for a Duffel offer in a canonical shape (free / penalty / not allowed / unknown / allowed-unknown-fee). Surfaces slice-level conditions, applied private fares, airline-credit applicability, and loyalty programme support.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["display_offer_conditions"],
                    "description": "Must be exactly `display_offer_conditions` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/DisplayOfferConditionsInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#quote_stay": {
      "post": {
        "operationId": "quote_stay",
        "summary": "Convert a Duffel Stays rate into a confirmed quote.",
        "description": "Convert a Duffel Stays rate into a confirmed quote. Returns the cancellation timeline, payment type (pay_now / deposit / guarantee), supported loyalty programme, and rate conditions. Hand the `quoteId` to `book_stay` to complete the booking.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["quote_stay"],
                    "description": "Must be exactly `quote_stay` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/QuoteStayInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#book_stay": {
      "post": {
        "operationId": "book_stay",
        "summary": "Complete a Duffel Stays booking from a confirmed quoteId.",
        "description": "Complete a Duffel Stays booking from a confirmed quoteId. Supports loyalty programme account numbers, special requests, and Customer User linkage (unlocks Travel Support Assistant for the guest). The session traveler is auto-linked via ensure_flight_customer.",
        "tags": ["Bookings"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["book_stay"],
                    "description": "Must be exactly `book_stay` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/BookStayInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#cancel_order_quote": {
      "post": {
        "operationId": "cancel_order_quote",
        "summary": "Create an unconfirmed Duffel cancellation quote for a flight order.",
        "description": "Create an unconfirmed Duffel cancellation quote for a flight order. Returns refund destination, refund amount (if known), and any airline credits that will be issued. Use before actually cancelling — the operator or traveler must then call `confirm_cancel_order` within the quote expiry window.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["cancel_order_quote"],
                    "description": "Must be exactly `cancel_order_quote` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/CancelOrderQuoteInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#confirm_cancel_order": {
      "post": {
        "operationId": "confirm_cancel_order",
        "summary": "Confirm a Duffel cancellation quote by id (from `cancel_order_quote`).",
        "description": "Confirm a Duffel cancellation quote by id (from `cancel_order_quote`). Must be called within the quote expiry. Returns the final refund + airline credit codes (credit_code is populated only after confirmation).",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["confirm_cancel_order"],
                    "description": "Must be exactly `confirm_cancel_order` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ConfirmCancelOrderInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#request_order_change": {
      "post": {
        "operationId": "request_order_change",
        "summary": "Kick off a Duffel order-change request — propose new slices for an existing confirmed flight order.",
        "description": "Kick off a Duffel order-change request — propose new slices for an existing confirmed flight order. Duffel returns one or more priced offers (each with change fee + new total + refund destination). Operator picks one and calls `confirm_order_change`. Use `display_offer_conditions` first to check whether the order is changeable + see penalty estimates.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["request_order_change"],
                    "description": "Must be exactly `request_order_change` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/RequestOrderChangeInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#select_order_change_offer": {
      "post": {
        "operationId": "select_order_change_offer",
        "summary": "Lock in one of the offers returned by `request_order_change` (creates an unconfirmed `order_change`).",
        "description": "Lock in one of the offers returned by `request_order_change` (creates an unconfirmed `order_change`). Operator must call `confirm_order_change` within `expiresAt`. No money moves yet.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["select_order_change_offer"],
                    "description": "Must be exactly `select_order_change_offer` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/SelectOrderChangeOfferInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#confirm_order_change": {
      "post": {
        "operationId": "confirm_order_change",
        "summary": "Pay + confirm a Duffel `order_change` (id from `select_order_change_offer`).",
        "description": "Pay + confirm a Duffel `order_change` (id from `select_order_change_offer`). Returns the final change with `confirmedAt`. Once confirmed, the airline reissues the ticket and any refund is sent to `refundTo`.",
        "tags": ["Settlement"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["confirm_order_change"],
                    "description": "Must be exactly `confirm_order_change` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ConfirmOrderChangeInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#list_airline_credits": {
      "post": {
        "operationId": "list_airline_credits",
        "summary": "List a traveler's Duffel airline credits (unused tickets, MCOs, vouchers).",
        "description": "List a traveler's Duffel airline credits (unused tickets, MCOs, vouchers). Resolves the Duffel CustomerUser from the Clerk session when available. Returns availability state (available / spent / invalidated / expired), expiry, and a totals-by-currency roll-up.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["list_airline_credits"],
                    "description": "Must be exactly `list_airline_credits` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ListAirlineCreditsInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#manage_stays_negotiated_rate": {
      "post": {
        "operationId": "manage_stays_negotiated_rate",
        "summary": "Create, update, or delete a Duffel Stays negotiated rate (corporate RAC).",
        "description": "Create, update, or delete a Duffel Stays negotiated rate (corporate RAC). Pass `action: create` with displayName + rateAccessCode + accommodationIds; `action: update` with negotiatedRateId + any field to patch; `action: delete` with negotiatedRateId.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["manage_stays_negotiated_rate"],
                    "description": "Must be exactly `manage_stays_negotiated_rate` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ManageStaysNegotiatedRateInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#faucet_drip": {
      "post": {
        "operationId": "faucet_drip",
        "summary": "Drip 20 testnet units of USDC or EURC from the Circle faucet to any address on a supported testnet (ARC-TESTNET default).",
        "description": "Drip 20 testnet units of USDC or EURC from the Circle faucet to any address on a supported testnet (ARC-TESTNET default). Rate-limited upstream by Circle. Returns ok/status/message envelope.",
        "tags": ["Utilities"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["faucet_drip"],
                    "description": "Must be exactly `faucet_drip` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/FaucetDripInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#scan_document": {
      "post": {
        "operationId": "scan_document",
        "summary": "Extract structured fields from a travel / finance document (invoice, receipt, boarding pass, or ID).",
        "description": "Extract structured fields from a travel / finance document (invoice, receipt, boarding pass, or ID). Accepts either a public URL or inline base64. Returns a typed object plus provider + model + latency.",
        "tags": ["Documents"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["scan_document"],
                    "description": "Must be exactly `scan_document` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/ScanDocumentInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    },
    "/api/agent/dispatch#check_travel_eligibility": {
      "post": {
        "operationId": "check_travel_eligibility",
        "summary": "Verify a traveler is eligible for an upcoming trip.",
        "description": "Verify a traveler is eligible for an upcoming trip. Reads their passport from the encrypted vault (signals only, never PII), checks expiry + 6-month rule, runs visa-rules lookup, returns a pass/warn/block verdict with enum reason codes the UI renders into human copy. Safe for agents — no names, dates of birth, or passport numbers in the response.",
        "tags": ["Compliance"],
        "security": [
          {
            "ClerkApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenantId", "tool", "args"],
                "properties": {
                  "tenantId": {
                    "type": "string",
                    "description": "The calling tenant's id (tenant_...)."
                  },
                  "userId": {
                    "type": "string",
                    "description": "Optional subject for the call; omitted in service-account mode (we use svc:${keyId} automatically)."
                  },
                  "tool": {
                    "type": "string",
                    "enum": ["check_travel_eligibility"],
                    "description": "Must be exactly `check_travel_eligibility` for this operation."
                  },
                  "args": {
                    "$ref": "#/components/schemas/CheckTravelEligibilityInput"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool executed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "latencyMs": {
                      "type": "number"
                    },
                    "priceMicroUsdc": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "402": {
            "description": "Tenant spend cap exceeded."
          },
          "404": {
            "description": "Tool or tenant not found."
          },
          "500": {
            "description": "Tool execution failed."
          }
        }
      }
    }
  }
}
