{
  "openapi": "3.1.0",
  "jsonSchemaDialect": "https://spec.openapis.org/oas/3.1/dialect/base",
  "info": {
    "title": "Untap agent API",
    "version": "1.3.2",
    "summary": "UK train, flight and TfL compensation checks and claim instructions, with no sign-in.",
    "description": "The no-sign-in tools of the Untap MCP server (https://untap.money/api/mcp) as plain JSON over HTTPS. Each endpoint takes the same input and returns the same result as the MCP tool of the same name. Untap works out eligibility, the amount, the deadline and exactly how to submit on the train operator’s, airline’s or TfL’s own form. The person, or their agent on their instruction, submits the claim there. Untap files nothing, is free and takes nothing from what is paid. Nothing sent to these endpoints is saved to an account; each call leaves a usage record with the tool name, outcome and duration. Limits are per caller per hour, keyed on a salted digest of the IP address. Lookups that call an outside data source also share a daily allowance across all callers (National Rail 600, flight status 150); a repeated lookup is served from a shared cache and does not count. For higher volumes, write to contact@untap.money.",
    "contact": {
      "name": "Untap",
      "email": "contact@untap.money",
      "url": "https://untap.money/connect/docs"
    },
    "termsOfService": "https://untap.money/terms"
  },
  "servers": [
    {
      "url": "https://untap.money"
    }
  ],
  "externalDocs": {
    "description": "Tool documentation",
    "url": "https://untap.money/connect/docs"
  },
  "security": [],
  "paths": {
    "/api/agent/v1/find_money_owed": {
      "post": {
        "operationId": "find_money_owed",
        "summary": "Find money you may be owed",
        "description": "Takes a plain-language description of what happened (a late or cancelled train, a delayed or cancelled flight, a TfL overcharge, a parking ticket, a council tax, water or broadband problem) and returns the UK refund and compensation schemes Untap covers that may apply. For each one it gives the fact that decides it, the Untap check that covers it and Untap’s free guide. It also picks out any flight number, date, time or amount in the text. Matching is by keywords, not a full reading of the situation, so the list is a starting point rather than a verdict. No sign-in needed. Journey details are not saved to an account; limited usage metadata is recorded. Limit: 240 calls per caller per hour.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "situation": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 4000,
                    "description": "What happened, in the person’s own words. For example: \"my train from Brighton to Victoria was 40 minutes late on Monday\" or \"I think my council tax band is wrong\"."
                  }
                },
                "required": [
                  "situation"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The result, as plain text and as structured JSON (the same object the MCP server returns as structuredContent). A result that asks the caller to wait (retry_after_seconds) also carries a Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Present when result.retry_after_seconds is set: seconds to wait before calling again with the same input.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "tool",
                    "text",
                    "result"
                  ],
                  "properties": {
                    "tool": {
                      "type": "string",
                      "const": "find_money_owed"
                    },
                    "text": {
                      "type": "string",
                      "description": "The full result as readable text, including any claim pack, steps and deadline."
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "const": "ok"
                        },
                        "matches": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "title": {
                                "type": "string"
                              },
                              "summary": {
                                "type": "string"
                              },
                              "next_tool": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Open tool that answers it now, with no sign-in."
                              },
                              "account_tool": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "guide_url": {
                                "type": "string"
                              },
                              "wizard_url": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "ask": {
                                "type": "string",
                                "description": "What to ask or gather next."
                              }
                            },
                            "required": [
                              "id",
                              "title",
                              "summary",
                              "ask"
                            ],
                            "additionalProperties": true
                          }
                        },
                        "spotted": {
                          "type": "object",
                          "properties": {
                            "flight_number": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "date": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "time": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "amount": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "additionalProperties": true
                        },
                        "note": {
                          "type": "string"
                        },
                        "all_checks": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "title": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      },
                      "required": [
                        "status",
                        "matches"
                      ],
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid JSON or does not match the input schema.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 1 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "The caller’s hourly limit or the daily lookup cap was reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The tool could not run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/v1/check_train_delay": {
      "post": {
        "operationId": "check_train_delay",
        "summary": "Check a delayed train for Delay Repay",
        "description": "Checks a late or cancelled train in Great Britain against National Rail’s historic running records and works out Delay Repay. Takes the two stations (names, partial names or three-letter codes), the date and roughly when the train left; the operator, ticket type and price paid are optional. Returns the matched train with scheduled and actual times, the delay at the destination, the operator and its scheme, the amount (or the percentage when no price is given), the claim deadline, a claim pack with the value for each form field, and the details needed to save the claim to an Untap account. When several trains fit, the result lists them, each with a service_id. The records cover roughly the last year and each day appears the day after. They hold direct trains only, so a journey with a change is checked one train at a time. When nothing could be learned, status is data_not_available with delay_known false, a reason, retryable and retry_after_seconds or try_again_on. When National Rail is slow the lookup carries on in the background, and a retry after retry_after_seconds is answered from the cache. No sign-in needed. Journey details are not saved to an account; limited usage metadata is recorded. Limit: 40 calls per caller per hour.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "from": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 80,
                    "description": "Station the person got on at. A name, part of a name or a three-letter code: \"Brighton\", \"Kings Cross\", \"BTN\"."
                  },
                  "to": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 80,
                    "description": "Station the person got off at, in the same forms."
                  },
                  "date": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 40,
                    "description": "Date of travel. YYYY-MM-DD is best; \"25/09/2026\", \"25 September\", \"yesterday\" and \"last Friday\" also work."
                  },
                  "departure_time": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 20
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Roughly when the train left the first station, UK time: \"08:05\", \"8am\", \"around 8\". Needed to find the train unless service_id is given."
                  },
                  "operator": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 60
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Train company if known, as the person says it: \"Southern\", \"GWR\", \"Avanti\". Used to narrow the match."
                  },
                  "ticket_type": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 40
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "As printed: \"Anytime Return\", \"Off-Peak Single\", \"Advance\", \"Annual Season\", \"Monthly Season\", \"Flexi Season\". A return halves the single fare the amount is worked from. A season is valued per journey from its length; a season with no length gets no amount."
                  },
                  "price_paid": {
                    "anyOf": [
                      {
                        "anyOf": [
                          {
                            "type": "string",
                            "maxLength": 40
                          },
                          {
                            "type": "number",
                            "minimum": 0,
                            "maximum": 1000000
                          }
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "What the ticket cost: \"£24.50\", 24.50 or 2450 (pence). For a season ticket, the price of the whole season. Needed for a cash amount; without it the percentage is returned."
                  },
                  "service_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 40
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The service_id of a train listed in an earlier result. With it, that train is checked directly."
                  }
                },
                "required": [
                  "from",
                  "to",
                  "date"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The result, as plain text and as structured JSON (the same object the MCP server returns as structuredContent). A result that asks the caller to wait (retry_after_seconds) also carries a Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Present when result.retry_after_seconds is set: seconds to wait before calling again with the same input.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "tool",
                    "text",
                    "result"
                  ],
                  "properties": {
                    "tool": {
                      "type": "string",
                      "const": "check_train_delay"
                    },
                    "text": {
                      "type": "string",
                      "description": "The full result as readable text, including any claim pack, steps and deadline."
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "check": {
                          "type": "string",
                          "const": "train_delay"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "owed",
                            "not_owed",
                            "needs_confirmation",
                            "needs_more_information",
                            "data_not_available",
                            "limit_reached"
                          ]
                        },
                        "headline": {
                          "type": "string"
                        },
                        "reason": {
                          "type": "string",
                          "description": "Why there is no answer. Train: future_date, same_day, older_than_records, records_slow, upstream_error, records_not_complete, no_direct_services, running_details_missing. Flight: future_date, records_slow, upstream_error."
                        },
                        "delay_known": {
                          "type": "boolean",
                          "description": "Always false on data_not_available: nothing was learned about the delay. Never read this as \"no delay\"."
                        },
                        "retryable": {
                          "type": "boolean",
                          "description": "Whether calling again with the same input can change the answer."
                        },
                        "retry_after_seconds": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "When retryable, how long to wait before calling again. Also sent as the Retry-After header."
                        },
                        "try_again_on": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "When retryable on a later day, the date to call again, YYYY-MM-DD."
                        },
                        "journey": {
                          "type": "object",
                          "properties": {
                            "from": {
                              "type": "object",
                              "properties": {
                                "crs": {
                                  "type": "string",
                                  "description": "Three-letter station code."
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "crs",
                                "name"
                              ],
                              "additionalProperties": true
                            },
                            "to": {
                              "type": "object",
                              "properties": {
                                "crs": {
                                  "type": "string",
                                  "description": "Three-letter station code."
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "crs",
                                "name"
                              ],
                              "additionalProperties": true
                            },
                            "date": {
                              "type": "string",
                              "description": "YYYY-MM-DD"
                            },
                            "departure_time_given": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "additionalProperties": true
                        },
                        "service": {
                          "type": "object",
                          "properties": {
                            "service_id": {
                              "type": "string"
                            },
                            "operator": {
                              "type": "string"
                            },
                            "operator_code": {
                              "type": "string"
                            },
                            "scheduled_departure": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "actual_departure": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "scheduled_arrival": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "actual_arrival": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "delay_minutes": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Minutes late at the destination. Null when cancelled."
                            },
                            "cancelled": {
                              "type": "boolean"
                            },
                            "matched_on": {
                              "type": "string"
                            }
                          },
                          "additionalProperties": true
                        },
                        "verdict": {
                          "type": "object",
                          "properties": {
                            "owed": {
                              "type": "boolean"
                            },
                            "amount": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "pence": {
                                      "type": "integer",
                                      "description": "Amount in minor units: pence for GBP, cents for EUR."
                                    },
                                    "currency": {
                                      "type": "string",
                                      "enum": [
                                        "GBP",
                                        "EUR"
                                      ]
                                    },
                                    "display": {
                                      "type": "string",
                                      "description": "Formatted for people, for example \"£12.50\"."
                                    }
                                  },
                                  "required": [
                                    "pence",
                                    "currency",
                                    "display"
                                  ],
                                  "additionalProperties": true
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "percent": {
                              "type": "integer"
                            },
                            "percent_of": {
                              "type": "string"
                            },
                            "scheme": {
                              "type": "string"
                            },
                            "operator": {
                              "type": "string"
                            },
                            "threshold_minutes": {
                              "type": "integer"
                            },
                            "reason": {
                              "type": "string"
                            },
                            "needs_price": {
                              "type": "boolean"
                            },
                            "amount_known": {
                              "type": "boolean"
                            },
                            "needs_season_length": {
                              "type": "boolean"
                            },
                            "amount_basis": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "additionalProperties": true
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "additionalProperties": true
                        },
                        "given_time_found": {
                          "type": "boolean",
                          "description": "On needs_confirmation: whether any candidate left at exactly the time given."
                        },
                        "candidates": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "service_id": {
                                "type": "string",
                                "description": "Pass this back as service_id to check this train."
                              },
                              "scheduled_departure": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "HH:MM"
                              },
                              "scheduled_arrival": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "HH:MM"
                              },
                              "journey_minutes": {
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              },
                              "operator": {
                                "type": "string"
                              },
                              "operator_code": {
                                "type": "string"
                              },
                              "minutes_from_given_time": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Signed. Negative means it left before the time given."
                              }
                            },
                            "required": [
                              "service_id",
                              "scheduled_departure",
                              "operator"
                            ],
                            "additionalProperties": true
                          },
                          "description": "On needs_confirmation, and alongside some data_not_available results."
                        },
                        "match_hints": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "What to compare against the ticket to pick a candidate."
                        },
                        "how_to_confirm": {
                          "type": "string"
                        },
                        "problems": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": {
                                "type": "string"
                              },
                              "message": {
                                "type": "string"
                              },
                              "candidates": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": true
                                }
                              }
                            },
                            "required": [
                              "field"
                            ],
                            "additionalProperties": true
                          }
                        },
                        "deadline": {
                          "type": "object",
                          "properties": {
                            "date": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Last day to claim, YYYY-MM-DD. Null when it cannot be computed."
                            },
                            "days_remaining": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            },
                            "expired": {
                              "type": "boolean"
                            },
                            "description": {
                              "type": "string",
                              "description": "The rule in plain English."
                            }
                          },
                          "required": [
                            "description"
                          ],
                          "additionalProperties": true
                        },
                        "claim_pack": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "where_to_claim": {
                                  "type": "object",
                                  "properties": {
                                    "organisation": {
                                      "type": "string"
                                    },
                                    "form_url": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "The organisation’s own claim page."
                                    },
                                    "how": {
                                      "type": "string"
                                    }
                                  },
                                  "additionalProperties": true
                                },
                                "fields": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "label": {
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": [
                                          "string",
                                          "null"
                                        ],
                                        "description": "Null when the person must supply it; see note."
                                      },
                                      "note": {
                                        "type": "string"
                                      }
                                    },
                                    "required": [
                                      "label",
                                      "value"
                                    ],
                                    "additionalProperties": true
                                  },
                                  "description": "Each claim form field with the value to enter."
                                },
                                "evidence": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "deadline": {
                                  "type": "object",
                                  "properties": {
                                    "date": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Last day to claim, YYYY-MM-DD. Null when it cannot be computed."
                                    },
                                    "days_remaining": {
                                      "type": [
                                        "integer",
                                        "null"
                                      ]
                                    },
                                    "expired": {
                                      "type": "boolean"
                                    },
                                    "description": {
                                      "type": "string",
                                      "description": "The rule in plain English."
                                    }
                                  },
                                  "required": [
                                    "description"
                                  ],
                                  "additionalProperties": true
                                },
                                "escalation": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "body": {
                                          "type": "string"
                                        },
                                        "url": {
                                          "type": "string"
                                        },
                                        "when": {
                                          "type": "string"
                                        }
                                      },
                                      "additionalProperties": true
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "you_submit_it": {
                                  "type": "string"
                                },
                                "calendar_ics": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "iCalendar text for the deadline."
                                }
                              },
                              "additionalProperties": true,
                              "description": "Everything needed to fill in the claim form. Present only when money is owed."
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "save_claim": {
                          "type": "object",
                          "properties": {
                            "ready": {
                              "type": "boolean",
                              "description": "True when save_claim can be called with `arguments` as they are."
                            },
                            "missing": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Argument paths still needed before saving."
                            },
                            "arguments": {
                              "type": "object",
                              "additionalProperties": true,
                              "description": "Arguments for the save_claim account tool."
                            }
                          },
                          "required": [
                            "ready",
                            "missing",
                            "arguments"
                          ],
                          "additionalProperties": true
                        },
                        "assumptions": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "operator_scheme_note": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "automatic_compensation": {
                          "description": "Whether the operator pays some delays without a claim, and for which tickets."
                        },
                        "source": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string"
                            },
                            "url": {
                              "type": "string"
                            },
                            "rules_last_checked": {
                              "type": "string"
                            }
                          },
                          "additionalProperties": true
                        },
                        "code": {
                          "type": "string",
                          "description": "On limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                        }
                      },
                      "required": [
                        "check",
                        "status"
                      ],
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid JSON or does not match the input schema.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 1 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "The caller’s hourly limit or the daily lookup cap was reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The tool could not run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/v1/check_flight_compensation": {
      "post": {
        "operationId": "check_flight_compensation",
        "summary": "Check a flight for UK261 or EU261 compensation",
        "description": "Works out compensation for a delayed or cancelled flight under UK261 or EU261. Takes the flight number and date. What happened comes from flight-status records, which cover about the last year, or from what_happened and arrival_delay_minutes when given. Returns the matched route, the arrival delay, the distance band, the amount per passenger, the extraordinary-circumstances caveat, the airline’s claim page, the dispute body for a refused claim, deadline guidance, a claim pack and the details needed to save the claim to an Untap account. When the airports given differ from the flight-status record, the result says so. No sign-in needed. Journey details are not saved to an account; limited usage metadata is recorded. Limit: 40 calls per caller per hour.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "flight_number": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 10,
                    "description": "Airline code and number, as on the booking: \"BA2551\", \"U2 8123\"."
                  },
                  "date": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 40,
                    "description": "Date the flight was due to depart, local time. YYYY-MM-DD is best."
                  },
                  "from_airport": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 3,
                        "maxLength": 3
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Three-letter departure airport code, if known: \"LGW\". Helps pick the right flight on multi-stop numbers."
                  },
                  "to_airport": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 3,
                        "maxLength": 3
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Three-letter arrival airport code, if known: \"BCN\"."
                  },
                  "what_happened": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "delayed",
                          "cancelled",
                          "on_time",
                          "denied_boarding"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "What happened, if known. When left out, Untap looks it up in flight-status records."
                  },
                  "arrival_delay_minutes": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 4320
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "How late the flight arrived at the gate, in minutes, if the person knows. Compensation turns on arrival, not departure."
                  },
                  "cancellation_notice_days": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 365
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "For a cancellation: how many days before departure the airline told the person. 14 or more means no compensation."
                  },
                  "price_paid": {
                    "anyOf": [
                      {
                        "anyOf": [
                          {
                            "type": "string",
                            "maxLength": 40
                          },
                          {
                            "type": "number",
                            "minimum": 0,
                            "maximum": 1000000
                          }
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Optional. Not used for the amount, which is fixed in law, but needed to save the claim to an account."
                  }
                },
                "required": [
                  "flight_number",
                  "date"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The result, as plain text and as structured JSON (the same object the MCP server returns as structuredContent). A result that asks the caller to wait (retry_after_seconds) also carries a Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Present when result.retry_after_seconds is set: seconds to wait before calling again with the same input.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "tool",
                    "text",
                    "result"
                  ],
                  "properties": {
                    "tool": {
                      "type": "string",
                      "const": "check_flight_compensation"
                    },
                    "text": {
                      "type": "string",
                      "description": "The full result as readable text, including any claim pack, steps and deadline."
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "check": {
                          "type": "string",
                          "const": "flight_compensation"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "owed",
                            "not_owed",
                            "needs_more_information",
                            "data_not_available",
                            "limit_reached"
                          ]
                        },
                        "headline": {
                          "type": "string"
                        },
                        "reason": {
                          "type": "string",
                          "description": "Why there is no answer. Train: future_date, same_day, older_than_records, records_slow, upstream_error, records_not_complete, no_direct_services, running_details_missing. Flight: future_date, records_slow, upstream_error."
                        },
                        "delay_known": {
                          "type": "boolean",
                          "description": "Always false on data_not_available: nothing was learned about the delay. Never read this as \"no delay\"."
                        },
                        "retryable": {
                          "type": "boolean",
                          "description": "Whether calling again with the same input can change the answer."
                        },
                        "retry_after_seconds": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "When retryable, how long to wait before calling again. Also sent as the Retry-After header."
                        },
                        "try_again_on": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "When retryable on a later day, the date to call again, YYYY-MM-DD."
                        },
                        "flight": {
                          "type": "object",
                          "properties": {
                            "flight_number": {
                              "type": "string"
                            },
                            "airline": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "date": {
                              "type": "string"
                            },
                            "from_airport": {
                              "type": "string"
                            },
                            "from_airport_name": {
                              "type": "string"
                            },
                            "to_airport": {
                              "type": "string"
                            },
                            "to_airport_name": {
                              "type": "string"
                            },
                            "scheduled_departure": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "scheduled_arrival": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "actual_arrival": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "arrival_delay_minutes": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            },
                            "cancelled": {
                              "type": "boolean"
                            },
                            "outcome_source": {
                              "type": "string",
                              "enum": [
                                "you_told_us",
                                "flight_records"
                              ]
                            }
                          },
                          "additionalProperties": true
                        },
                        "verdict": {
                          "type": "object",
                          "properties": {
                            "owed": {
                              "type": "boolean"
                            },
                            "amount_per_passenger": {
                              "anyOf": [
                                {
                                  "type": "object",
                                  "properties": {
                                    "pence": {
                                      "type": "integer",
                                      "description": "Amount in minor units: pence for GBP, cents for EUR."
                                    },
                                    "currency": {
                                      "type": "string",
                                      "enum": [
                                        "GBP",
                                        "EUR"
                                      ]
                                    },
                                    "display": {
                                      "type": "string",
                                      "description": "Formatted for people, for example \"£12.50\"."
                                    }
                                  },
                                  "required": [
                                    "pence",
                                    "currency",
                                    "display"
                                  ],
                                  "additionalProperties": true
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "scheme": {
                              "type": "string",
                              "description": "UK261 or EU261."
                            },
                            "distance_km": {
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "distance_band": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "reason": {
                              "type": "string"
                            }
                          },
                          "additionalProperties": true
                        },
                        "extraordinary_circumstances": {
                          "description": "The caveat that an airline can refuse for causes outside its control."
                        },
                        "claim_route": {
                          "type": "object",
                          "properties": {
                            "airline": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "claim_url": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "adr_body": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "adr_url": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "if_refused": {
                              "description": "Where to go if refused."
                            }
                          },
                          "additionalProperties": true
                        },
                        "route_mismatch": {
                          "anyOf": [
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "problems": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": {
                                "type": "string"
                              },
                              "message": {
                                "type": "string"
                              },
                              "candidates": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": true
                                }
                              }
                            },
                            "required": [
                              "field"
                            ],
                            "additionalProperties": true
                          }
                        },
                        "deadline": {
                          "type": "object",
                          "properties": {
                            "date": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Last day to claim, YYYY-MM-DD. Null when it cannot be computed."
                            },
                            "days_remaining": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            },
                            "expired": {
                              "type": "boolean"
                            },
                            "description": {
                              "type": "string",
                              "description": "The rule in plain English."
                            }
                          },
                          "required": [
                            "description"
                          ],
                          "additionalProperties": true
                        },
                        "claim_pack": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "where_to_claim": {
                                  "type": "object",
                                  "properties": {
                                    "organisation": {
                                      "type": "string"
                                    },
                                    "form_url": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "The organisation’s own claim page."
                                    },
                                    "how": {
                                      "type": "string"
                                    }
                                  },
                                  "additionalProperties": true
                                },
                                "fields": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "label": {
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": [
                                          "string",
                                          "null"
                                        ],
                                        "description": "Null when the person must supply it; see note."
                                      },
                                      "note": {
                                        "type": "string"
                                      }
                                    },
                                    "required": [
                                      "label",
                                      "value"
                                    ],
                                    "additionalProperties": true
                                  },
                                  "description": "Each claim form field with the value to enter."
                                },
                                "evidence": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "deadline": {
                                  "type": "object",
                                  "properties": {
                                    "date": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Last day to claim, YYYY-MM-DD. Null when it cannot be computed."
                                    },
                                    "days_remaining": {
                                      "type": [
                                        "integer",
                                        "null"
                                      ]
                                    },
                                    "expired": {
                                      "type": "boolean"
                                    },
                                    "description": {
                                      "type": "string",
                                      "description": "The rule in plain English."
                                    }
                                  },
                                  "required": [
                                    "description"
                                  ],
                                  "additionalProperties": true
                                },
                                "escalation": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "body": {
                                          "type": "string"
                                        },
                                        "url": {
                                          "type": "string"
                                        },
                                        "when": {
                                          "type": "string"
                                        }
                                      },
                                      "additionalProperties": true
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "you_submit_it": {
                                  "type": "string"
                                },
                                "calendar_ics": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "iCalendar text for the deadline."
                                }
                              },
                              "additionalProperties": true,
                              "description": "Everything needed to fill in the claim form. Present only when money is owed."
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "save_claim": {
                          "type": "object",
                          "properties": {
                            "ready": {
                              "type": "boolean",
                              "description": "True when save_claim can be called with `arguments` as they are."
                            },
                            "missing": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Argument paths still needed before saving."
                            },
                            "arguments": {
                              "type": "object",
                              "additionalProperties": true,
                              "description": "Arguments for the save_claim account tool."
                            }
                          },
                          "required": [
                            "ready",
                            "missing",
                            "arguments"
                          ],
                          "additionalProperties": true
                        },
                        "assumptions": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "source": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string"
                            },
                            "url": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "additionalProperties": true
                        }
                      },
                      "required": [
                        "check",
                        "status"
                      ],
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid JSON or does not match the input schema.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 1 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "The caller’s hourly limit or the daily lookup cap was reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The tool could not run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/v1/check_tfl_journeys": {
      "post": {
        "operationId": "check_tfl_journeys",
        "summary": "Check TfL journeys for overcharges",
        "description": "Checks Transport for London contactless or Oyster journeys for overcharges: incomplete journeys (no touch out, so the maximum fare was charged) and missed Hopper fares. Takes journey rows from a journey history, or the text of the CSV download from a TfL account. PDFs and images are not accepted. TfL refunds an incomplete journey as the maximum fare minus the fare for the journey actually made. Without the destination, the refund shown is an upper limit equal to the whole charge; with intended_destination on the row, it is an estimate from the usual fare to that station. Returns the refundable journeys and total, older journeys outside TfL’s 8 week window, how to claim in the TfL account, a claim pack and the details needed to save the journeys to an Untap account. It does not check service delays on the Tube, DLR, Elizabeth line or Overground, or Santander Cycles; the result lists these under not_checked. No sign-in needed. Journey details are not saved to an account; limited usage metadata is recorded. Limit: 240 calls per caller per hour.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "journeys": {
                    "anyOf": [
                      {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "date": {
                              "type": "string",
                              "description": "Journey date as YYYY-MM-DD."
                            },
                            "start_time": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Tap-in time as HH:MM, or null."
                            },
                            "end_time": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Tap-out time as HH:MM, or null."
                            },
                            "mode": {
                              "type": "string",
                              "enum": [
                                "tube",
                                "bus",
                                "overground",
                                "elizabeth",
                                "dlr",
                                "tram",
                                "cable_car",
                                "thameslink",
                                "unknown"
                              ],
                              "description": "Transport mode for this row, or \"unknown\" when the statement does not say."
                            },
                            "from_location": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Tap-in station / stop name, or null if not shown."
                            },
                            "to_location": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Tap-out station / stop name, or null for incomplete journeys."
                            },
                            "bus_route": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Bus route number for bus rows, otherwise null."
                            },
                            "fare_pence": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 100000,
                              "description": "Charge for this row in pence. £2.20 = 220."
                            },
                            "is_max_fare": {
                              "type": "boolean",
                              "description": "True if the statement labels this as a max-fare charge for a failed revenue inspection."
                            },
                            "is_incomplete": {
                              "type": "boolean",
                              "description": "True if this journey has no tap-out recorded (e.g. label \"Incomplete\" or \"No exit\")."
                            },
                            "is_hopper_free": {
                              "type": [
                                "boolean",
                                "null"
                              ],
                              "description": "Optional. True when the statement shows this fare as a free Hopper fare (a second bus or tram within 60 minutes)."
                            },
                            "is_auto_corrected": {
                              "type": [
                                "boolean",
                                "null"
                              ],
                              "description": "Optional. True when the statement says TfL has already corrected this journey (for example \"Auto-completed\" or \"Adjusted\")."
                            },
                            "is_daily_cap_hit": {
                              "type": [
                                "boolean",
                                "null"
                              ],
                              "description": "Optional. True when the statement marks this row as the one where the daily cap was reached."
                            },
                            "is_weekly_cap_hit": {
                              "type": [
                                "boolean",
                                "null"
                              ],
                              "description": "Optional. True when the statement marks this row as the one where the weekly cap was reached."
                            },
                            "intended_destination": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "maxLength": 80
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "Optional, for an incomplete journey with no touch out: the station the person was travelling to. With it, the refund is estimated as the fare charged minus the usual fare to that station. Without it, the figure is an upper limit equal to the whole charge."
                            }
                          },
                          "required": [
                            "date",
                            "start_time",
                            "end_time",
                            "mode",
                            "from_location",
                            "to_location",
                            "bus_route",
                            "fare_pence",
                            "is_max_fare",
                            "is_incomplete"
                          ],
                          "additionalProperties": false
                        },
                        "maxItems": 500
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Journey rows from a TfL contactless or Oyster journey history. Used when csv_text is not given."
                  },
                  "csv_text": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 300000
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The text of the CSV journey history downloaded from a TfL account. Takes priority over journeys."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The result, as plain text and as structured JSON (the same object the MCP server returns as structuredContent). A result that asks the caller to wait (retry_after_seconds) also carries a Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Present when result.retry_after_seconds is set: seconds to wait before calling again with the same input.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "tool",
                    "text",
                    "result"
                  ],
                  "properties": {
                    "tool": {
                      "type": "string",
                      "const": "check_tfl_journeys"
                    },
                    "text": {
                      "type": "string",
                      "description": "The full result as readable text, including any claim pack, steps and deadline."
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "check": {
                          "type": "string",
                          "const": "tfl_journeys"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "owed",
                            "not_owed",
                            "needs_more_information",
                            "limit_reached"
                          ]
                        },
                        "reason": {
                          "type": "string",
                          "description": "On needs_more_information: csv_too_large, no_journeys or csv_unreadable."
                        },
                        "headline": {
                          "type": "string"
                        },
                        "journeys_checked": {
                          "type": "integer"
                        },
                        "period": {
                          "type": "object",
                          "properties": {
                            "start": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "end": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "additionalProperties": true
                        },
                        "refundable": {
                          "type": "object",
                          "properties": {
                            "count": {
                              "type": "integer"
                            },
                            "total": {
                              "type": "object",
                              "properties": {
                                "pence": {
                                  "type": "integer",
                                  "description": "Amount in minor units: pence for GBP, cents for EUR."
                                },
                                "currency": {
                                  "type": "string",
                                  "enum": [
                                    "GBP",
                                    "EUR"
                                  ]
                                },
                                "display": {
                                  "type": "string",
                                  "description": "Formatted for people, for example \"£12.50\"."
                                }
                              },
                              "required": [
                                "pence",
                                "currency",
                                "display"
                              ],
                              "additionalProperties": true
                            },
                            "total_is_upper_bound": {
                              "type": "boolean"
                            },
                            "total_is_estimate": {
                              "type": "boolean"
                            },
                            "journeys": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "date": {
                                    "type": "string"
                                  },
                                  "description": {
                                    "type": "string"
                                  },
                                  "charged": {
                                    "type": "object",
                                    "properties": {
                                      "pence": {
                                        "type": "integer",
                                        "description": "Amount in minor units: pence for GBP, cents for EUR."
                                      },
                                      "currency": {
                                        "type": "string",
                                        "enum": [
                                          "GBP",
                                          "EUR"
                                        ]
                                      },
                                      "display": {
                                        "type": "string",
                                        "description": "Formatted for people, for example \"£12.50\"."
                                      }
                                    },
                                    "required": [
                                      "pence",
                                      "currency",
                                      "display"
                                    ],
                                    "additionalProperties": true
                                  },
                                  "refund": {
                                    "type": "object",
                                    "properties": {
                                      "pence": {
                                        "type": "integer",
                                        "description": "Amount in minor units: pence for GBP, cents for EUR."
                                      },
                                      "currency": {
                                        "type": "string",
                                        "enum": [
                                          "GBP",
                                          "EUR"
                                        ]
                                      },
                                      "display": {
                                        "type": "string",
                                        "description": "Formatted for people, for example \"£12.50\"."
                                      }
                                    },
                                    "required": [
                                      "pence",
                                      "currency",
                                      "display"
                                    ],
                                    "additionalProperties": true
                                  },
                                  "refund_is_upper_bound": {
                                    "type": "boolean"
                                  },
                                  "refund_is_estimate": {
                                    "type": "boolean"
                                  },
                                  "reason": {
                                    "type": "string",
                                    "enum": [
                                      "incomplete_journey",
                                      "missed_hopper_fare"
                                    ]
                                  },
                                  "explanation": {
                                    "type": "string"
                                  }
                                },
                                "additionalProperties": true
                              }
                            }
                          },
                          "additionalProperties": true
                        },
                        "outside_window": {
                          "type": "object",
                          "properties": {
                            "count": {
                              "type": "integer"
                            },
                            "total": {
                              "type": "object",
                              "properties": {
                                "pence": {
                                  "type": "integer",
                                  "description": "Amount in minor units: pence for GBP, cents for EUR."
                                },
                                "currency": {
                                  "type": "string",
                                  "enum": [
                                    "GBP",
                                    "EUR"
                                  ]
                                },
                                "display": {
                                  "type": "string",
                                  "description": "Formatted for people, for example \"£12.50\"."
                                }
                              },
                              "required": [
                                "pence",
                                "currency",
                                "display"
                              ],
                              "additionalProperties": true
                            },
                            "note": {
                              "type": "string"
                            }
                          },
                          "additionalProperties": true
                        },
                        "already_corrected_by_tfl": {
                          "type": "integer"
                        },
                        "checked_for": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "What the check looks for."
                        },
                        "not_checked": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "what": {
                                "type": "string"
                              },
                              "why": {
                                "type": "string"
                              },
                              "guide": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "additionalProperties": true
                          },
                          "description": "What the check does not look for, so \"nothing found\" is not read as \"nothing owed\" for these."
                        },
                        "how_to_claim": {
                          "description": "Steps in the TfL account."
                        },
                        "deadline": {
                          "type": "object",
                          "properties": {
                            "date": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Last day to claim, YYYY-MM-DD. Null when it cannot be computed."
                            },
                            "days_remaining": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            },
                            "expired": {
                              "type": "boolean"
                            },
                            "description": {
                              "type": "string",
                              "description": "The rule in plain English."
                            }
                          },
                          "required": [
                            "description"
                          ],
                          "additionalProperties": true
                        },
                        "claim_pack": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "where_to_claim": {
                                  "type": "object",
                                  "properties": {
                                    "organisation": {
                                      "type": "string"
                                    },
                                    "form_url": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "The organisation’s own claim page."
                                    },
                                    "how": {
                                      "type": "string"
                                    }
                                  },
                                  "additionalProperties": true
                                },
                                "fields": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "label": {
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": [
                                          "string",
                                          "null"
                                        ],
                                        "description": "Null when the person must supply it; see note."
                                      },
                                      "note": {
                                        "type": "string"
                                      }
                                    },
                                    "required": [
                                      "label",
                                      "value"
                                    ],
                                    "additionalProperties": true
                                  },
                                  "description": "Each claim form field with the value to enter."
                                },
                                "evidence": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "deadline": {
                                  "type": "object",
                                  "properties": {
                                    "date": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Last day to claim, YYYY-MM-DD. Null when it cannot be computed."
                                    },
                                    "days_remaining": {
                                      "type": [
                                        "integer",
                                        "null"
                                      ]
                                    },
                                    "expired": {
                                      "type": "boolean"
                                    },
                                    "description": {
                                      "type": "string",
                                      "description": "The rule in plain English."
                                    }
                                  },
                                  "required": [
                                    "description"
                                  ],
                                  "additionalProperties": true
                                },
                                "escalation": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "body": {
                                          "type": "string"
                                        },
                                        "url": {
                                          "type": "string"
                                        },
                                        "when": {
                                          "type": "string"
                                        }
                                      },
                                      "additionalProperties": true
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                },
                                "you_submit_it": {
                                  "type": "string"
                                },
                                "calendar_ics": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "iCalendar text for the deadline."
                                }
                              },
                              "additionalProperties": true,
                              "description": "Everything needed to fill in the claim form. Present only when money is owed."
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "save_claim": {
                          "type": "object",
                          "properties": {
                            "ready": {
                              "type": "boolean",
                              "description": "True when save_claim can be called with `arguments` as they are."
                            },
                            "missing": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Argument paths still needed before saving."
                            },
                            "arguments": {
                              "type": "object",
                              "additionalProperties": true,
                              "description": "Arguments for the save_claim account tool."
                            }
                          },
                          "required": [
                            "ready",
                            "missing",
                            "arguments"
                          ],
                          "additionalProperties": true
                        }
                      },
                      "required": [
                        "check",
                        "status"
                      ],
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid JSON or does not match the input schema.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 1 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "The caller’s hourly limit or the daily lookup cap was reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The tool could not run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/v1/get_delay_repay_rules": {
      "post": {
        "operationId": "get_delay_repay_rules",
        "summary": "Delay Repay rules for a train operator",
        "description": "Returns one train operator’s Delay Repay rules: the delay at which it starts paying, each payout tier, the claim deadline, the link to its claim form, any automatic or one-click scheme, and the date the rules were last checked against the operator’s own page. Accepts the operator’s name as people say it, such as Avanti, GWR or Southern. No sign-in needed. Limit: 240 calls per caller per hour.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "operator": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 60,
                    "description": "Train company name as people say it: \"Avanti\", \"GWR\", \"Southern\", \"LNER\", or a two-letter operator code."
                  }
                },
                "required": [
                  "operator"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The result, as plain text and as structured JSON (the same object the MCP server returns as structuredContent). A result that asks the caller to wait (retry_after_seconds) also carries a Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Present when result.retry_after_seconds is set: seconds to wait before calling again with the same input.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "tool",
                    "text",
                    "result"
                  ],
                  "properties": {
                    "tool": {
                      "type": "string",
                      "const": "get_delay_repay_rules"
                    },
                    "text": {
                      "type": "string",
                      "description": "The full result as readable text, including any claim pack, steps and deadline."
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "check": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "ok",
                            "needs_more_information"
                          ]
                        },
                        "operators": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "On needs_more_information: the operators covered."
                        },
                        "operator": {
                          "type": "string"
                        },
                        "operator_code": {
                          "type": "string"
                        },
                        "scheme": {
                          "type": "string",
                          "description": "DR15 or DR30."
                        },
                        "threshold_minutes": {
                          "type": "integer"
                        },
                        "tiers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "From how many minutes, what percentage, of which fare."
                        },
                        "basis": {
                          "type": "string"
                        },
                        "cancellation": {
                          "type": "string"
                        },
                        "claim_deadline_days": {
                          "type": "integer"
                        },
                        "claim_url": {
                          "type": "string"
                        },
                        "season_tickets": {
                          "anyOf": [
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "automatic_compensation": {
                          "anyOf": [
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "note": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "escalation": {
                          "type": "object",
                          "properties": {
                            "body": {
                              "type": "string"
                            },
                            "url": {
                              "type": "string"
                            },
                            "when": {
                              "type": "string"
                            }
                          },
                          "additionalProperties": true
                        },
                        "guide_url": {
                          "type": "string"
                        },
                        "rules_last_checked": {
                          "type": "string",
                          "description": "YYYY-MM-DD"
                        },
                        "rules_source": {
                          "type": "object",
                          "properties": {
                            "url": {
                              "type": "string"
                            },
                            "how_checked": {
                              "type": "string"
                            },
                            "note": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "additionalProperties": true
                        },
                        "rule_record": {
                          "anyOf": [
                            {
                              "type": "object",
                              "additionalProperties": true,
                              "description": "The matching record in the open rules dataset."
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "status"
                      ],
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid JSON or does not match the input schema.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 1 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "The caller’s hourly limit or the daily lookup cap was reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The tool could not run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/v1/get_claim_instructions": {
      "post": {
        "operationId": "get_claim_instructions",
        "summary": "How to submit a train, flight or TfL claim",
        "description": "Returns how to submit one train, flight or TfL compensation claim on the company’s own form. Takes the claim type and the train operator or airline, with the journey date, ticket type, where it was booked and the airports as optional extras. Returns the eligibility rules for that company and claim type, the official claim page (marked unverified where Untap could not confirm it), numbered submission steps, each form field with where to find its value, the evidence to attach, the deadline (as a date when the journey date is given), any company rule on who may submit, what to expect after submitting and when to chase, the escalation route (operator to the Rail Ombudsman; airline to its dispute scheme, the CAA or a national enforcement body; TfL to London TravelWatch) and the sources with the dates they were checked. Covers every train operator in Untap’s Delay Repay engine, TfL and the airlines UK travellers fly most. Facts Untap has not verified come back marked as unknown rather than estimated. No sign-in needed. Journey details are not saved to an account; limited usage metadata is recorded. Limit: 240 calls per caller per hour.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "claim_type": {
                    "type": "string",
                    "enum": [
                      "train_delay",
                      "train_cancellation",
                      "flight_delay",
                      "flight_cancellation",
                      "denied_boarding",
                      "tfl_incomplete_journey",
                      "tfl_overcharge"
                    ],
                    "description": "What the claim is for: a late or cancelled train, a delayed or cancelled flight, denied boarding, a TfL incomplete journey or another TfL overcharge."
                  },
                  "company": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 80
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "The train operator or airline, by name or code as people say it: \"Southern\", \"LNER\", \"easyJet\", \"BA\", \"U2\". Not needed for TfL."
                  },
                  "journey_date": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 40
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Date of travel, YYYY-MM-DD. With it, the result gives the last day to claim as a date."
                  },
                  "ticket_type": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 40
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Ticket type as printed, such as \"Anytime Return\", \"Advance Single\" or \"Season\". Decides the rail return-ticket rule."
                  },
                  "booked_via": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "operator_direct",
                          "third_party_retailer",
                          "travel_agent",
                          "package_holiday"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Where the ticket was bought: from the operator or airline itself, from a ticket retailer such as Trainline, through a travel agent, or as part of a package holiday."
                  },
                  "departure_airport": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 3,
                        "maxLength": 3
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Three-letter departure airport code, such as \"CDG\". Decides whether UK261 or EU261 applies, and with the arrival airport, the distance band."
                  },
                  "arrival_airport": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 3,
                        "maxLength": 3
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Three-letter arrival airport code, such as \"LHR\"."
                  }
                },
                "required": [
                  "claim_type"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The result, as plain text and as structured JSON (the same object the MCP server returns as structuredContent). A result that asks the caller to wait (retry_after_seconds) also carries a Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Present when result.retry_after_seconds is set: seconds to wait before calling again with the same input.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "tool",
                    "text",
                    "result"
                  ],
                  "properties": {
                    "tool": {
                      "type": "string",
                      "const": "get_claim_instructions"
                    },
                    "text": {
                      "type": "string",
                      "description": "The full result as readable text, including any claim pack, steps and deadline."
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "check": {
                          "type": "string",
                          "const": "claim_instructions"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "ok",
                            "needs_more_information"
                          ]
                        },
                        "claim_type": {
                          "type": "string"
                        },
                        "mode": {
                          "type": "string",
                          "enum": [
                            "rail",
                            "flight",
                            "tfl"
                          ]
                        },
                        "problems": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": {
                                "type": "string"
                              },
                              "message": {
                                "type": "string"
                              },
                              "candidates": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": true
                                }
                              }
                            },
                            "required": [
                              "field"
                            ],
                            "additionalProperties": true
                          }
                        },
                        "company": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string"
                            },
                            "code": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "kind": {
                              "type": "string",
                              "enum": [
                                "operator",
                                "airline",
                                "tfl"
                              ]
                            }
                          },
                          "additionalProperties": true
                        },
                        "regime": {
                          "type": "object",
                          "properties": {
                            "scheme": {
                              "type": "string",
                              "enum": [
                                "UK261",
                                "EU261",
                                "unknown"
                              ]
                            },
                            "reason": {
                              "type": "string"
                            }
                          },
                          "additionalProperties": true
                        },
                        "eligibility": {
                          "type": "object",
                          "properties": {
                            "rules": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            }
                          },
                          "additionalProperties": true
                        },
                        "where_to_claim": {
                          "type": "object",
                          "properties": {
                            "organisation": {
                              "type": "string"
                            },
                            "form_url": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "form_url_verified": {
                              "type": "boolean"
                            },
                            "fallback_contact_url": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "note": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "additionalProperties": true
                        },
                        "steps": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "form_fields": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": {
                                "type": "string"
                              },
                              "where_to_find": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "evidence": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "deadline": {
                          "type": "object",
                          "properties": {
                            "date": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Last day to claim, YYYY-MM-DD. Null when it cannot be computed."
                            },
                            "days_remaining": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            },
                            "expired": {
                              "type": "boolean"
                            },
                            "description": {
                              "type": "string",
                              "description": "The rule in plain English."
                            }
                          },
                          "required": [
                            "description"
                          ],
                          "additionalProperties": true
                        },
                        "who_may_submit": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "rule": {
                                "type": "string"
                              },
                              "source": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "type": "string"
                                  },
                                  "url": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                },
                                "additionalProperties": true
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "booking_channel": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "booked_via": {
                                  "type": "string"
                                },
                                "note": {
                                  "type": "string"
                                },
                                "source": {
                                  "anyOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "name": {
                                          "type": "string"
                                        },
                                        "url": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        }
                                      },
                                      "additionalProperties": true
                                    },
                                    {
                                      "type": "null"
                                    }
                                  ]
                                }
                              },
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "after_submission": {
                          "type": "object",
                          "properties": {
                            "acknowledgement": {
                              "type": "string"
                            },
                            "response_time": {
                              "description": "Sourced text, or null."
                            },
                            "chase": {
                              "type": "string"
                            }
                          },
                          "additionalProperties": true
                        },
                        "escalation": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "step": {
                                "type": "integer"
                              },
                              "body": {
                                "type": "string"
                              },
                              "url": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "when": {
                                "type": "string"
                              },
                              "time_limit": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "source": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "name": {
                                        "type": "string"
                                      },
                                      "url": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      }
                                    },
                                    "additionalProperties": true
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "sources": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "url": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "related_checks": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "tool": {
                                "type": "string"
                              },
                              "purpose": {
                                "type": "string"
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "submission_note": {
                          "type": "string"
                        },
                        "guide_url": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "check",
                        "status",
                        "claim_type"
                      ],
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid JSON or does not match the input schema.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 1 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "The caller’s hourly limit or the daily lookup cap was reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The tool could not run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/v1/scan_for_claims": {
      "post": {
        "operationId": "scan_for_claims",
        "summary": "Scan emails for train, flight and TfL claims",
        "description": "Reads up to 25 emails (sender, subject, date and plain-text body) and picks out the ones that point to a train, flight or TfL claim: booking confirmations, delay and cancellation notices, airline schedule changes and denied boarding, TfL incomplete journey and maximum fare emails, and claim acknowledgements and decisions. Detection is by sender domain, subject pattern and fixed phrases, with no language model. For each match it returns the type, the signals that matched, the booking reference, dates, flight number, stations or airports, times and amounts it could read, a confidence level, a deadline hint, and the Untap check that fits with its arguments filled in and any missing ones listed. Emails with no signal are listed by position. Each body is read up to 20,000 characters. Nothing from the emails is stored; the usage record holds counts only. No sign-in needed. Limit: 240 calls per caller per hour.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "emails": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "from": {
                          "type": "string",
                          "maxLength": 500,
                          "description": "The From line as received, such as \"Trainline <auto-confirm@info.thetrainline.com>\"."
                        },
                        "subject": {
                          "type": "string",
                          "maxLength": 1000,
                          "description": "The subject line."
                        },
                        "date": {
                          "type": "string",
                          "maxLength": 100,
                          "description": "When the email was sent: ISO 8601 or the raw Date header."
                        },
                        "body_text": {
                          "type": "string",
                          "maxLength": 200000,
                          "description": "The plain-text body. Only the first 20,000 characters are read."
                        }
                      },
                      "required": [
                        "from",
                        "subject",
                        "date",
                        "body_text"
                      ],
                      "additionalProperties": false
                    },
                    "minItems": 1,
                    "maxItems": 25,
                    "description": "Up to 25 emails, each with its sender, subject, date and plain-text body."
                  }
                },
                "required": [
                  "emails"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The result, as plain text and as structured JSON (the same object the MCP server returns as structuredContent). A result that asks the caller to wait (retry_after_seconds) also carries a Retry-After header.",
            "headers": {
              "Retry-After": {
                "description": "Present when result.retry_after_seconds is set: seconds to wait before calling again with the same input.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "tool",
                    "text",
                    "result"
                  ],
                  "properties": {
                    "tool": {
                      "type": "string",
                      "const": "scan_for_claims"
                    },
                    "text": {
                      "type": "string",
                      "description": "The full result as readable text, including any claim pack, steps and deadline."
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "check": {
                          "type": "string",
                          "const": "scan_for_claims"
                        },
                        "status": {
                          "type": "string",
                          "const": "ok"
                        },
                        "emails_scanned": {
                          "type": "integer"
                        },
                        "candidate_count": {
                          "type": "integer"
                        },
                        "candidates": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "email_index": {
                                "type": "integer"
                              },
                              "type": {
                                "type": "string",
                                "enum": [
                                  "train_booking",
                                  "train_disruption",
                                  "flight_booking",
                                  "flight_disruption",
                                  "tfl_charge",
                                  "claim_update"
                                ]
                              },
                              "mode": {
                                "type": "string",
                                "enum": [
                                  "rail",
                                  "flight",
                                  "tfl"
                                ]
                              },
                              "subtype": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "company": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "name": {
                                        "type": "string"
                                      },
                                      "code": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "kind": {
                                        "type": "string"
                                      }
                                    },
                                    "additionalProperties": true
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "signals": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "extracted": {
                                "type": "object",
                                "additionalProperties": true
                              },
                              "confidence": {
                                "type": "string",
                                "enum": [
                                  "high",
                                  "medium",
                                  "low"
                                ]
                              },
                              "deadline_hint": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "date": {
                                        "type": [
                                          "string",
                                          "null"
                                        ],
                                        "description": "Last day to claim, YYYY-MM-DD. Null when it cannot be computed."
                                      },
                                      "days_remaining": {
                                        "type": [
                                          "integer",
                                          "null"
                                        ]
                                      },
                                      "expired": {
                                        "type": "boolean"
                                      },
                                      "description": {
                                        "type": "string",
                                        "description": "The rule in plain English."
                                      }
                                    },
                                    "required": [
                                      "description"
                                    ],
                                    "additionalProperties": true
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "next_tool": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "type": "string"
                                  },
                                  "arguments": {
                                    "type": "object",
                                    "additionalProperties": true
                                  },
                                  "missing": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    },
                                    "description": "Arguments the email did not give."
                                  },
                                  "note": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "name",
                                  "arguments",
                                  "missing"
                                ],
                                "additionalProperties": true
                              },
                              "instructions_tool": {
                                "anyOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "name": {
                                        "type": "string"
                                      },
                                      "arguments": {
                                        "type": "object",
                                        "additionalProperties": true
                                      },
                                      "missing": {
                                        "type": "array",
                                        "items": {
                                          "type": "string"
                                        },
                                        "description": "Arguments the email did not give."
                                      },
                                      "note": {
                                        "type": "string"
                                      }
                                    },
                                    "required": [
                                      "name",
                                      "arguments",
                                      "missing"
                                    ],
                                    "additionalProperties": true
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "email_index",
                              "type",
                              "mode",
                              "next_tool"
                            ],
                            "additionalProperties": true
                          }
                        },
                        "no_signal": {
                          "description": "Emails that showed nothing claimable."
                        },
                        "notes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "check",
                        "status",
                        "candidates"
                      ],
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid JSON or does not match the input schema.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is larger than 1 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "The caller’s hourly limit or the daily lookup cap was reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "The tool could not run.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "message"
                  ],
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Machine code: invalid_json, invalid_input, unknown_tool, body_too_large, limit_reached or internal_error."
                    },
                    "message": {
                      "type": "string",
                      "description": "Plain-English explanation."
                    },
                    "issues": {
                      "type": "array",
                      "description": "For invalid_input: each field that failed and why.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "code": {
                      "type": "string",
                      "description": "For limit_reached: caller_limit, daily_cap, degraded_limit or no_client_ip."
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}