Overview

The Airport Pickups London (APL) API lets you get real-time transfer quotes and create bookings for airport, cruise port, and train station transfers across the UK.

  • All UK airports including Heathrow (T2–T5), Gatwick (North & South), Stansted, Luton, London City, Manchester, Birmingham, Edinburgh, and more
  • Cruise ports: Southampton, Dover, Portsmouth, Tilbury, Harwich
  • Transfers to/from any UK address or postcode
  • Fixed prices — no surge pricing
  • Free cancellation & free child seats on request
  • Meet & greet included for airport pickups

Testing the discovery endpoints. The agent card, server card and this API are meant to be read by an agent runtime (Google ADK / Vertex Agent Builder, an MCP SDK client, your own orchestrator) calling them directly over HTTP. The browsing tools inside consumer chat apps (Gemini, ChatGPT, Claude chat) often refuse to fetch machine-readable URLs and report a client-side policy error such as PERMISSION_DENIED; that is not a block on this server — every endpoint answers 200 to any user agent and /mcp and /a2a carry open CORS. Test with curl or a real client.

Authentication

MCP and A2A need no credentials to start. Since 30 September 2026 the MCP endpoint (/mcp) and A2A message/send accept anonymous callers: quotes, service information, flight validation, bookings (passenger e-mail required) and booking management with the booking reference + passenger e-mail, subject to per-address hourly limits (5 bookings, 30 quotes). An API key or OAuth identifies a registered partner and raises the limits.

The REST API below requires an API key sent in the x-api-key header. Registration is instant (POST /a2a/register).

// Example header
x-api-key: your-api-key-here

Your API key is linked to your account configuration (account ID, payment type, etc). If you are already a registered APL partner or agency, your API key has been assigned to you — contact us at support@aplcars.com or call 020 3988 2168 to receive it. For new AI agents, you can self-register instantly.

Keep your API key secure. Do not expose it in client-side code or public repositories. If compromised, contact us immediately for a replacement.

Base URL

https://mcp.airport-pickups-london.com/api

All endpoint paths below are relative to this base URL.

Sandbox (test) keys

Partners are normally issued two keys: a sandbox key for building and testing your integration, and a live key for real bookings. There is no separate URL — the same base URL and the same endpoints are used for both; the key alone decides the behaviour.

EndpointWith a sandbox keyWith a live key
/quoteReal prices — identical to live, including date and seasonal pricingReal prices
/bookReturns a reference beginning APL-SANDBOX-. No reservation is created and no driver is dispatchedCreates a real reservation
/lookup-booking, /booking-status, /track, /amend-booking, /cancel-bookingWill not find a sandbox booking — nothing was stored, so expect “not found”Work normally
Expected behaviour, not a fault: if you book with the sandbox key and then try to look it up, track it or cancel it, you will get “booking not found”. That is correct — sandbox bookings are not stored. To test the full lifecycle (lookup, amend, track, cancel) use your live key on a genuine future booking; our standard policy allows free cancellation up to 12 hours before pickup.

Recommended sequence: build and verify /quote and /book against the sandbox key, then switch the key to go live — no code changes are needed.

Get Quote

POST /api/quote

Get available car types and prices for a transfer. Use this to show pricing to your customers before they book.

Request Body

ParameterTypeRequiredDescription
origin string required Pickup location — airport name, full address, or postcode (e.g. "Heathrow Terminal 5", "SW1A 2AA")
destination string required Dropoff location — full address, postcode, or airport name
passengers number optional Number of passengers. Used to recommend the right car. REST default: 1 (server-to-server callers hold this fact already); the MCP tools make no such assumption — see MCP Tools.
suitcases number optional Number of suitcases / large bags (default: 0)
transfer_date string optional Date in YYYY-MM-DD format (e.g. "2026-03-15"). Defaults to today.
transfer_time string optional Time in HH:MM format (e.g. "14:30"). Defaults to 2 hours from now.
Example Request
curl -X POST https://mcp.airport-pickups-london.com/api/quote \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "origin": "Heathrow Terminal 5",
    "destination": "10 Downing Street, London, SW1A 2AA",
    "passengers": 2,
    "suitcases": 2,
    "transfer_date": "2026-03-15",
    "transfer_time": "14:30"
  }'
Example Response
{
  "pickup": "London Heathrow Airport, Terminal 5",
  "dropoff": "10 Downing Street, Downing Street, London SW1A 2AA, UK",
  "transfer_date": "2026-03-15",
  "transfer_time": "14:30",
  "passengers": 2,
  "recommended_car_type": "Saloon",
  "duration": "51 minutes",
  "cars": [
    {
      "car_type": "Saloon",
      "price_gbp": 88,
      "max_passengers": 3,
      "max_bags": 3
    },
    {
      "car_type": "People Carrier",
      "price_gbp": 98,
      "max_passengers": 5,
      "max_bags": 5
    },
    {
      "car_type": "8 Seater",
      "price_gbp": 119,
      "max_passengers": 8,
      "max_bags": 8
    }
  ],
  "meeting_point": {
    "name": "Heathrow T5",
    "instructions": "Our driver will hold a board with your name inside the terminal..."
  }
}

Validate Flight

POST /api/validate-flight

Validate a flight number and get flight details including airline name, arrival airport, terminal, and arrival time. Use this before booking to verify the customer’s flight and auto-detect the correct terminal. Works with flights within the next few days (FlightStats live data) and has static terminal mapping as fallback for future dates.

Request Body

ParameterTypeRequiredDescription
flight_numberstringYesFlight number (e.g. “BA2534”, “EK007”, “AA38”)
datestringYesFlight date in YYYY-MM-DD format
Response Example
{
  "valid": true,
  "airline": "British Airways",
  "flight_number": "BA2534",
  "arrival_airport": "Heathrow",
  "arrival_terminal": "T5",
  "arrival_time": "14:30",
  "departure_airport": "DXB",
  "source": "flightstats"
}

If the flight cannot be verified, returns { "valid": false, "message": "..." }. This never blocks booking — the customer can still proceed without flight validation.

Tip: For airport pickups, call this before booking to show the customer their flight details and auto-detected terminal. The POST /api/book endpoint also validates the flight automatically, so this call is optional but improves UX.

Create Booking

POST /api/book

Create a confirmed transfer booking. This creates a real reservation — only call after your customer confirms.

This endpoint creates live bookings. Always get a quote first and confirm with your customer before calling this endpoint.

Request Body

ParameterTypeRequiredDescription
origin string required Pickup location
destination string required Dropoff location
transfer_date string required Date in YYYY-MM-DD format
transfer_time string required Time in HH:MM format
passenger_name string required Full name of the lead passenger
passenger_phone string required Phone number with country code (e.g. "+447123456789")
passenger_email string recommended Email for booking confirmation and manage-booking link. Optional on REST only because partner systems send their own confirmations; required on the MCP tool and for anonymous callers (with the reference it is the customer's key to the booking).
passengers number optional Number of passengers. REST default: 1 — send the real figure; the MCP booking tool requires it (why the difference).
suitcases number optional Number of suitcases (REST default: 1; required on the MCP tool)
car_type string optional Car type from the quote (e.g. "Saloon", "People Carrier"). REST only: the smallest car that fits is selected if omitted. The MCP tool requires the customer's own choice.
door_number string conditional House/building number. Required when destination is a postcode (e.g. "12", "Flat 3").
flight_number string conditional Flight number — required for airport pickups, optional for dropoffs (e.g. "BA2534"). Auto-validates and detects terminal.
cruise_name string conditional Ship/cruise name for port transfers (e.g. "P&O Ventura")
train_number string conditional Train number or origin for station transfers
special_requests string optional Any special requirements (e.g. "child seat needed", "wheelchair access")
Conditional fields: Include flight_number for airport pickups (required) or dropoffs (optional), cruise_name for port transfers, door_number when destination is a postcode.
Example Request
curl -X POST https://mcp.airport-pickups-london.com/api/book \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "origin": "Heathrow Terminal 5",
    "destination": "10 Downing Street, London, SW1A 2AA",
    "transfer_date": "2026-03-15",
    "transfer_time": "14:30",
    "passengers": 2,
    "suitcases": 2,
    "car_type": "Saloon",
    "passenger_name": "John Smith",
    "passenger_phone": "+447123456789",
    "passenger_email": "john@example.com",
    "door_number": "10",
    "flight_number": "BA2534",
    "special_requests": "Child seat needed"
  }'
Example Response
{
  "booking_ref": "APL-X7K9M2",
  "external_ref": 954226,
  "status": "confirmed",
  "pickup": "London Heathrow Airport, Terminal 5",
  "dropoff": "10 Downing Street, Downing Street, London SW1A 2AA, UK",
  "date": "2026-03-15",
  "time": "14:30",
  "car_type": "Saloon",
  "price_gbp": 88,
  "passengers": 2,
  "passenger": {
    "name": "John Smith",
    "phone": "+447123456789",
    "email": "john@example.com"
  },
  "duration": "51 minutes",
  "manage_booking_url": "https://www.airport-pickups-london.com/manage-booking.html?reservationId=954226&email=john%40example.com",
  "meeting_point": {
    "name": "Heathrow T5",
    "instructions": "Our driver will hold a board with your name inside the terminal..."
  },
  "flight_info": {
    "airline": "British Airways",
    "flight_number": "BA2534",
    "arrival_airport": "Heathrow",
    "arrival_terminal": "T5",
    "arrival_time": "14:30",
    "departure_airport": "DXB"
  },
  "message": "Booking confirmed! You can pay the driver in cash on the day, or if you prefer to pay by card, Apple Pay, or Google Pay, use the manage booking link."
}

Response Fields

FieldTypeDescription
booking_refstringAPL internal booking reference (e.g. "APL-X7K9M2")
external_refnumberReservation ID in the dispatch system
statusstringBooking status — "confirmed" on success
price_gbpnumberFinal price in GBP
manage_booking_urlstringLink to manage, track, pay by card/Apple Pay/Google Pay, and edit the booking
meeting_pointobjectDriver meeting instructions (for airport/station pickups)
flight_infoobject|nullFlight details from FlightStats validation (if flight_number was provided and verified). Contains: airline, flight_number, arrival_airport, arrival_terminal, arrival_time, departure_airport

Car Types

Available vehicle types returned in quote responses. Use the car_type value when creating a booking.

Car TypeMax PassengersMax BagsDescription
Saloon33Standard sedan — ideal for 1–3 passengers
People Carrier55Spacious MPV for families or groups
8 Seater88Minibus for larger groups
Executive Saloon33Premium sedan with luxury interior
Executive MPV77Premium people carrier
Executive 8 Seater88Premium minibus with luxury interior
Additional vehicle types (Estate, Mercedes S Class, 16/20/40 Seaters) may be available on certain routes.

Lookup Booking

POST /api/lookup-booking

Retrieve the current status and details of an existing booking.

Verification required. External and partner agents must supply both the booking reference and the passenger email that is on file — the same verification a passenger performs on the "Manage Booking" page. Requests missing either field return 400.

Request Body

ParameterTypeRequiredDescription
booking_ref string required APL booking reference (e.g. "APL-")
email string required Passenger email on the booking — must match exactly (case-insensitive)
Example Request
curl -X POST https://mcp.airport-pickups-london.com/api/lookup-booking \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "booking_ref": "APL-X7K9M2",
    "email": "john@example.com"
  }'
Example Response
{
  "booking_ref": "APL-X7K9M2",
  "status": "confirmed",
  "pickup": "London Heathrow Airport, Terminal 5",
  "dropoff": "10 Downing Street, London SW1A 2AA",
  "date": "2026-03-15",
  "time": "14:30",
  "car_type": "Saloon",
  "price_gbp": 88,
  "passenger": {
    "name": "John Smith",
    "phone": "+447123456789",
    "email": "john@example.com"
  },
  "driver": {
    "name": "David Johnson",
    "phone": "+447900123456"
  },
  "manage_booking_url": "https://www.airport-pickups-london.com/manage-booking.html?reservationId=954226&email=john%40example.com"
}

Response Fields

FieldTypeDescription
booking_refstringAPL booking reference
statusstringCurrent booking status (e.g. "confirmed", "completed", "cancelled")
passengerobjectPassenger name, phone, and email
driverobject|nullAssigned driver name and phone (null if not yet assigned)
manage_booking_urlstringLink to manage, track, and pay for the booking

Amend Booking

POST /api/amend-booking

Amend details on an existing booking. You can update one or more fields at a time — only include the fields you want to change.

Verification required. External and partner agents must supply both the booking reference and the passenger email on file (case-insensitive match). passenger_email itself cannot be changed via this endpoint — it is the customer's key to the booking; email corrections go to info@aplcars.com from the address used at booking.

Request Body

ParameterTypeRequiredDescription
booking_ref string required APL booking reference (e.g. "APL-")
email string required Passenger email on the booking — must match exactly
changes object required Object containing the fields to update (see below)

Amendable Fields (inside changes)

FieldTypeDescription
passenger_namestringUpdated passenger name
passenger_phonestringUpdated phone number
flight_numberstringUpdated flight number
special_requestsstringUpdated special requirements
transfer_datestringNew date in YYYY-MM-DD format
transfer_timestringNew time in HH:MM format
passengersnumberUpdated passenger count
Example Request
curl -X POST https://mcp.airport-pickups-london.com/api/amend-booking \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "booking_ref": "APL-X7K9M2",
    "email": "john@example.com",
    "changes": {
      "passenger_phone": "+447999888777",
      "flight_number": "BA2590",
      "transfer_time": "15:00"
    }
  }'
Example Response
{
  "success": true,
  "booking_ref": "APL-X7K9M2",
  "amended_fields": ["passenger_phone", "flight_number", "transfer_time"]
}

Response Fields

FieldTypeDescription
successbooleanWhether the amendment was applied
booking_refstringThe amended booking reference
amended_fieldsarrayList of field names that were successfully updated

Cancel Booking

POST /api/cancel-booking

Cancel an existing booking. Free cancellation is available 12 or more hours before the scheduled pickup time.

Cancellation policy: Free cancellation 12+ hours before pickup — no fee, full refund, for every cancellation made through this API. Within 12 hours the API rejects the cancellation — the customer must call the office (6–12 h: 50% of the fare; under 6 h: no refund).

Verification required. External and partner agents must supply both the booking reference and the passenger email on file.

Request Body

ParameterTypeRequiredDescription
booking_ref string required APL booking reference (e.g. "APL-")
email string required Passenger email on the booking — must match exactly
reason string optional Reason for cancellation
Example Request
curl -X POST https://mcp.airport-pickups-london.com/api/cancel-booking \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "booking_ref": "APL-X7K9M2",
    "email": "john@example.com",
    "reason": "Flight cancelled"
  }'
Example Response
{
  "success": true,
  "booking_ref": "APL-X7K9M2",
  "status": "cancelled",
  "hours_before_pickup": 26.5,
  "admin_fee": 0
}

Response Fields

FieldTypeDescription
successbooleanWhether the cancellation was processed
statusstring"cancelled" on success
hours_before_pickupnumberHours remaining before the scheduled pickup time
admin_feestringAlways "£0" — cancellations through this API carry no fee. Cancellations within 12 hours are rejected, not charged.

Track Driver

POST /api/track

Get live driver location and vehicle details for an active booking. Returns the assigned driver’s information, GPS coordinates, heading, speed, and estimated time of arrival.

GPS updates: Driver positions are updated every 2 minutes. If the driver is in a known tunnel (Heathrow tunnels, Limehouse Link, Blackwall Tunnel, etc.), the position is interpolated based on the last known location and heading.

Verification required. External and partner agents must supply both the booking reference and the passenger email on file.

Request Body

ParameterTypeRequiredDescription
booking_ref string required APL booking reference (e.g. "APL-")
email string required Passenger email on the booking — must match exactly
Example Request
curl -X POST https://mcp.airport-pickups-london.com/api/track \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "booking_ref": "APL-X7K9M2",
    "email": "john@example.com"
  }'
Example Response
{
  "booking_ref": "APL-X7K9M2",
  "driver": {
    "name": "David Johnson",
    "photo_url": "https://api.london-tech.com/drivers/photos/8042.jpg",
    "phone": "+447900123456",
    "pco_licence": "012345"
  },
  "vehicle": {
    "make": "Mercedes-Benz",
    "model": "E-Class",
    "colour": "Black",
    "registration": "AB12 CDE"
  },
  "position": {
    "latitude": 51.4700,
    "longitude": -0.4543,
    "heading": 85,
    "speed_mph": 42,
    "is_interpolated": false
  },
  "eta_minutes": 8
}

Response Fields

FieldTypeDescription
driverobjectDriver details: name, photo URL, phone number, and PCO licence number
vehicleobjectVehicle make, model, colour, and registration plate
positionobjectLive GPS coordinates (latitude, longitude), heading in degrees, speed in mph
position.is_interpolatedbooleanTrue if the driver is in a known tunnel and position is estimated
eta_minutesnumberEstimated time of arrival in minutes

MCP Protocol Model Context Protocol

Our server implements the Model Context Protocol (MCP) — the open standard used by Claude, Cursor, Windsurf, and other AI tools for connecting to external services. MCP provides tool-based access to quoting and booking via Streamable HTTP transport with OAuth 2.1 authentication.

When to use MCP vs REST API: Use MCP when your AI assistant or IDE natively supports it (Claude, Cursor, Windsurf, Claude Code). Use the REST API for direct programmatic integration from your own code.

Endpoint

MCP Server URL
https://mcp.airport-pickups-london.com/mcp

Authentication

The MCP server supports two authentication methods:

  • API Key — Send your key in the x-api-key header (same key as the REST API)
  • OAuth 2.1 — Automatic for Claude.ai Integrations and other OAuth-capable clients. Supports authorization code (with PKCE) and client credentials grants.

Connect to MCP

Claude.ai (Recommended)

The easiest way — no setup required:

  1. Go to Settings → Integrations → Add Custom Integration
  2. Enter: https://mcp.airport-pickups-london.com/mcp
  3. Ask Claude: “How much is a taxi from Heathrow to Oxford?”

Claude Desktop

Add to your claude_desktop_config.json:

Claude Desktop Config
{
  "mcpServers": {
    "airport-pickups-london": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://mcp.airport-pickups-london.com/mcp",
        "--header",
        "x-api-key:YOUR_API_KEY"
      ]
    }
  }
}

Claude Code (CLI)

Terminal
claude mcp add apl-transfers https://mcp.airport-pickups-london.com/mcp --header "x-api-key:YOUR_API_KEY"

Cursor / Windsurf / Other IDEs

Add the MCP server URL in your IDE’s MCP settings. Most IDEs support remote MCP servers via Streamable HTTP transport.

Example Prompts

Once connected, try these prompts in Claude to see the full flow. Claude will pick the right tool automatically — no need to name it.

Get a quote

  • “How much is a taxi from Heathrow T5 to Oxford for 2 people with 3 suitcases on 15 June at 2pm?”
  • “What’s the price for an 8-seater from Gatwick to Cambridge next Saturday morning?”
  • “I’m arriving at Southampton cruise port, need a car to London Paddington.”

Book a transfer

  • “Book a saloon from Heathrow T2 to W1K 1LN at 10:30 on 20 June for John Smith, phone +447123456789, email john@example.com, flight BA2534.”
  • “Book the executive MPV for 4 passengers from Stansted to Brighton on Friday 6pm, add a child seat for a 3-year-old.”

Manage an existing booking

  • “Look up booking APL-954226 using email john@example.com.”
  • “Change the flight number on booking APL-954226 to BA178 and push pickup to 11:00.”
  • “Where is my driver for booking APL-954226?”
  • “Cancel booking APL-954226 — free cancellation, pickup is in 3 days.”

Pickup and dropoff can be any UK airport, cruise port, rail station, or postcode. All prices are fixed, include tolls and parking, and come with free flight tracking.

MCP Tools

Eleven tools are available via the MCP server (quote, EU quote, flight validation, booking, lookup, amend, cancel, driver tracking, driver route, nearby cars, service info); tools/list is always the authoritative schema. The three most used are described here.

MCP vs REST — an intentional difference. The MCP tools are used by AI assistants talking to a customer, so they never assume what the customer has not said: no default passenger count, no automatically chosen car, email and WhatsApp consent required, an explicit confirmation step before cancelling. The REST endpoints above are server-to-server integrations where the partner system already holds those facts, so they keep defaults (1 passenger, smallest suitable car) for compatibility.

london_airport_transfer_quote

Get fixed-price quotes for airport and cruise port transfers. Returns all available car types with prices, capacity, and luggage info.

ParameterTypeRequiredDescription
originstringYesPickup location — airport name or address/postcode
destinationstringYesDropoff location — address, postcode, or airport
passengersintegerNoOnly if the customer said. No default — without it the result carries capacity_assessed: false, no fit flags and no recommended car
suitcasesintegerNoOnly if the customer said (medium suitcases; hand luggage does not count). Same rule as passengers
transfer_datestringYesTravel date, YYYY-MM-DD — the price depends on it
transfer_timestringNoHH:MM Europe/London. Never assumed; time of day does not change the price, only transfers under 6 hours ahead carry a last-minute surcharge. The result states its price_basis

book_london_airport_transfer

Create a confirmed reservation. Nothing is assumed on the customer’s behalf: the assistant must have asked for every required value below, shown the price, and received the customer’s confirmation. Returns a booking reference and management link for payment and live driver tracking.

ParameterTypeRequiredDescription
originstringYesPickup location
destinationstringYesDropoff location
transfer_datestringYesDate (YYYY-MM-DD)
transfer_timestringYesTime (HH:MM, Europe/London). Airport pickups: landing time + airport_wait_minutes
passenger_namestringYesFull name
passenger_phonestringYesPhone with country code
passenger_emailstringYesReceives the confirmation; with the booking reference it is the customer’s key to manage the booking
passengersintegerYesExact number travelling — asked, never assumed from the car
suitcasesintegerYesSuitcases / large bags (hand luggage does not count)
car_typestringYesThe car the customer chose from the quote — never selected for them
whatsapp_opt_inbooleanYesThe customer’s actual answer to “may we send updates to this number on WhatsApp?”
airport_wait_minutesintegerAirport pickupsMinutes after landing agreed with the customer (30 / 45 / 60 / 90). An airport pickup without it is refused with MISSING_FIELDS
flight_numberstringNoFlight number for airport pickups
door_numberstringNoBuilding number / name for postcode addresses
special_requestsstringNoe.g. “child seat needed”

cancel_booking additionally requires customer_confirmed: true, set only after the customer has been told exactly which booking will be cancelled and agreed; without it the tool answers CONFIRMATION_REQUIRED and nothing happens. The booking email cannot be changed through amend_booking.

validate_flight

Validate a flight number and get flight details including airline name, arrival airport, terminal, and arrival time. Use this before booking to verify the customer’s flight and auto-detect the correct terminal.

ParameterTypeRequiredDescription
flight_numberstringYesFlight number (e.g. “BA2534”, “EK007”)
datestringYesFlight date in YYYY-MM-DD format
Response
{
  "valid": true,
  "airline": "British Airways",
  "flight_number": "BA2534",
  "arrival_airport": "Heathrow",
  "arrival_terminal": "T5",
  "arrival_time": "14:30",
  "departure_airport": "DXB"
}

If the flight is not found or invalid, returns { "valid": false, "message": "..." }. Booking can still proceed without flight validation.

A2A Protocol Agent-to-Agent

The APL Transfer Agent implements Google's Agent-to-Agent (A2A) protocol, allowing any A2A-compatible AI agent to discover our services and request quotes or bookings via standard JSON-RPC 2.0 messages.

When to use A2A vs REST API: Use the REST API (/api/quote, /api/book) for direct programmatic integration. Use A2A (/a2a) when your AI agent needs to discover and communicate with APL using the standard A2A protocol.

How It Works

  1. Discovery — Your agent fetches /.well-known/agent.json to learn what APL can do
  2. Authentication — optional. No key is needed: anonymous agents can quote, validate flights, book, manage a booking (reference + passenger e-mail) and read back their own tasks, subject to per-address limits. A registered key (x-api-key, same key as the REST API) identifies your agent and raises the limits
  3. Send a message — POST a JSON-RPC 2.0 request to /a2a with a message/send method
  4. Get results — The response contains a task with status and artifacts (quote data or booking confirmation)

Base URL

https://mcp.airport-pickups-london.com

Available Skills

Skill IDNameDescription
get_quote Transfer Quoting Get fixed prices for all car types on any supported route
create_booking Transfer Booking Create a live reservation with passenger details

Agent Discovery

GET /.well-known/agent.json Public

Returns the Agent Card describing APL's capabilities, skills, and authentication requirements. No API key required.

Example Request
curl https://mcp.airport-pickups-london.com/.well-known/agent.json
Response

Returns a JSON Agent Card with:

  • name — Agent identifier (airport-pickups-london)
  • supported_interfaces — A2A endpoint URL and protocol version
  • skills — Available skills with descriptions, tags, and examples
  • security_schemes — How to authenticate (API key in x-api-key header, optional — anonymous access is allowed)
  • capabilities — Supported features (streaming, push notifications)

message/send

POST /a2a

Send a message to the APL agent. The agent processes the message, executes the appropriate skill, and returns a task with the result.

Task States

StateMeaning
completedSkill executed successfully — check artifacts for results
failedSkill execution failed — check status.message for error details
input-requiredAgent needs more information — check status.message for guidance

Option 1: DataPart (Recommended)

Send structured JSON data with a skill field for explicit routing, or omit it for auto-detection.

Get a Quote
curl -X POST https://mcp.airport-pickups-london.com/a2a \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "message/send",
    "params": {
      "message": {
        "role": "user",
        "parts": [{
          "type": "data",
          "mimeType": "application/json",
          "data": {
            "skill": "get_quote",
            "origin": "Heathrow",
            "destination": "W1K 1LN",
            "passengers": 2,
            "transfer_date": "2026-04-01",
            "transfer_time": "14:00"
          }
        }]
      }
    }
  }'
Quote Response (completed task with artifact)
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "id": "a1b2c3d4-...",
    "status": { "state": "completed" },
    "artifacts": [{
      "name": "quote",
      "parts": [{
        "type": "data",
        "mimeType": "application/json",
        "data": {
          "hub": "LHR",
          "zone": "W1",
          "direction": "from_hub",
          "recommended_car_type": "Saloon",
          "from_hub": [
            { "car_type": "Saloon", "price_gbp": 75, "max_passengers": 3 },
            { "car_type": "People Carrier", "price_gbp": 90, "max_passengers": 5 }
          ]
        }
      }]
    }]
  }
}
Create a Booking
curl -X POST https://mcp.airport-pickups-london.com/a2a \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "message/send",
    "params": {
      "message": {
        "role": "user",
        "parts": [{
          "type": "data",
          "mimeType": "application/json",
          "data": {
            "skill": "create_booking",
            "origin": "Heathrow Terminal 5",
            "destination": "10 Downing Street, SW1A 2AA",
            "transfer_date": "2026-04-01",
            "transfer_time": "14:00",
            "passenger_name": "John Smith",
            "passenger_phone": "+447123456789",
            "passenger_email": "john@example.com",
            "passengers": 2,
            "car_type": "Saloon",
            "flight_number": "BA2534",
            "door_number": "10"
          }
        }]
      }
    }
  }'
The create_booking skill creates real reservations. Always get a quote first and confirm with the end user before booking.

Option 2: TextPart (Natural Language)

Send plain text. The agent will return input-required with the expected JSON schema.

{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "message/send",
    "params": {
      "message": {
        "role": "user",
        "parts": [{
          "type": "text",
          "text": "How much is a ride from Heathrow to central London?"
        }]
      }
    }
  }

Auto-Detection

If you omit the skill field from a DataPart, the agent auto-detects:

  • Has passenger_name? → routes to create_booking
  • Has origin / destination? → routes to get_quote

tasks/get

POST /a2a

Retrieve a previously created task by its ID. Tasks are stored in memory for 1 hour.

Example Request
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tasks/get",
  "params": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}
Response

Returns the full task object with status, artifacts, and history. Returns error code -32001 if the task is not found or has expired.

tasks/cancel

POST /a2a

Cancel a task that is still in progress. Only tasks in submitted, working, or input-required states can be canceled.

Example Request
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tasks/cancel",
  "params": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Returns the updated task with status.state: "canceled", or error code -32002 if the task has already completed.

A2A JSON-RPC Errors

A2A uses JSON-RPC 2.0 error codes. All error responses follow this format:

{
  "jsonrpc": "2.0",
  "error": { "code": -32601, "message": "Method not found: foo/bar" },
  "id": 1
}
CodeNameMeaning
-32700Parse ErrorInvalid JSON in request body
-32600Invalid RequestMissing jsonrpc: "2.0" or method
-32601Method Not FoundUnknown method (only message/send, tasks/get, tasks/cancel supported)
-32602Invalid ParamsMissing or invalid parameters
-32603Internal ErrorServer-side error
-32000UnauthorizedInvalid API key (a missing key is accepted as anonymous access)
-32001Task Not FoundTask ID does not exist or has expired (1hr TTL)
-32002Task Not CancelableTask is already completed, failed, or canceled

Agent Registration

Already an APL partner or agency? You do not need to self-register. Your API key and account have already been configured with your specific settings (account ID, payment type, billing, etc). Contact us to receive your key:

For new AI agents and developers, get an API key instantly by self-registering below. No approval required — your key is returned immediately. Self-registered agents use APL’s default booking account.

POST /a2a/register

Public endpoint — no authentication needed. Rate limited to 3 registrations per IP per hour.

Request Body

FieldTypeRequiredDescription
namestringYesYour agent or company name
emailstringYesContact email (used for duplicate detection)
urlstringNoYour website URL

Example Request

{
  "name": "TravelBot AI",
  "email": "dev@travelbot.com",
  "url": "https://travelbot.com"
}

Example Response (201 Created)

{
  "agent_name": "TravelBot AI",
  "api_key": "a1b2c3d4e5f6...",
  "message": "API key created. Use this key in the x-api-key header for all A2A, REST API, and MCP requests."
}
Your API key works across all endpoints: REST API (/api/quote, /api/book), A2A protocol (/a2a), and MCP (/mcp).

Corporate Account Registration

For travel agencies, AI platforms, and corporate clients who need monthly invoicing or credit accounts. Applications are reviewed by our team within 1–2 business days.

POST /a2a/register/corporate

Public endpoint — no authentication needed. Rate limited to 3 per IP per hour. Your API key is issued but inactive until approved.

Request Body

FieldTypeRequiredDescription
Company Details
company_namestringYesLegal company name
company_reg_numberstringNoCompany registration number
vat_numberstringNoVAT number
company_addressstringNoRegistered address
Contact
contact_namestringYesPrimary contact name
emailstringYesContact email
phonestringNoPhone number
accounts_payable_namestringNoAP contact name
accounts_payable_emailstringNoAP email for invoices
Commercial
estimated_monthly_volumeintegerNoExpected monthly bookings
estimated_monthly_spendnumberNoExpected monthly spend (£)
preferred_vehiclesstringNoe.g. “Saloon, Executive, MPV”
primary_routesstringNoe.g. “Heathrow, Gatwick, Central London”
Billing
billing_typestringYesinvoice or credit_account
requested_credit_limitnumberNoRequested credit limit (£) — credit_account only
payment_termsintegerNo14, 30, or 60 days (default: 30)
urlstringNoCompany website
notesstringNoAdditional information

Example Request

{
  "company_name": "TravelTech AI Ltd",
  "company_reg_number": "12345678",
  "vat_number": "GB123456789",
  "company_address": "100 Innovation Way, London EC2A 1NT",
  "contact_name": "Sarah Johnson",
  "email": "sarah@traveltech-ai.com",
  "phone": "+44 20 7123 4567",
  "accounts_payable_email": "ap@traveltech-ai.com",
  "estimated_monthly_volume": 500,
  "estimated_monthly_spend": 25000,
  "preferred_vehicles": "Saloon, Executive, MPV",
  "primary_routes": "Heathrow, Gatwick, Central London hotels",
  "billing_type": "invoice",
  "payment_terms": 30,
  "url": "https://traveltech-ai.com"
}

Example Response (201 Created — Pending)

{
  "status": "pending",
  "company_name": "TravelTech AI Ltd",
  "message": "Corporate account application received. Our team will review your application and contact you within 1-2 business days. Your API key will be activated upon approval.",
  "contact": "corporate@aplcars.com"
}
What happens next?
  • Our team reviews your application (1–2 business days)
  • Upon approval, your API key is activated and billing type is set
  • You receive an email with your API key and account details
  • All bookings are invoiced monthly to your accounts payable contact

Error Handling

The API uses standard HTTP status codes. Error responses include a JSON body with an error field.

{
  "error": "Missing required fields: transfer_date, passenger_name"
}
StatusMeaningCommon Causes
400Bad RequestMissing/invalid fields, location not found, no vehicles available
401UnauthorizedMissing or invalid API key
429Rate LimitedToo many requests — max 60/minute per IP
500Server ErrorInternal error — please retry or contact support

Typical Integration Flow

  1. Get a quote — Call POST /api/quote with pickup, dropoff and date/time. Prices are final net prices — there is no discount negotiation.
  2. Show options — Display available car types and prices to your customer exactly as returned.
  3. Collect details — Gather passenger name, phone, email, flight number (if airport pickup), and door number (if postcode destination)
  4. Validate flight (airport pickups) — Call POST /api/validate-flight with the flight number and date to verify the flight and auto-detect the terminal. Show the customer: “Your flight BA2534 (British Airways) arrives at Heathrow T5 at 14:30”
  5. Create booking — Call POST /api/book with all details and the chosen car type. The system automatically validates the flight number and registers the correct terminal and landing time.
  6. Confirm to customer — Share the booking_ref, flight_info, and meeting_point instructions with your customer

Agency Portal

Manage your bookings, view reservation status, and track drivers through the agency portal:

https://agency.airport-pickups-london.com

Use the portal to:

  • Search and view all your reservations
  • Edit booking details and passenger information
  • Track driver status in real time
  • View booking history and invoices
Your agency login credentials are provided separately by APL. Contact us if you need access.

Support

For API integration support, account setup, or technical issues: