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
Authentication
All requests require an API key sent in the x-api-key header.
// 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 [email protected] or call 020 3988 2168 to receive it. For new AI agents, you can self-register instantly.
Base URL
https://mcp.airport-pickups-london.com/api
All endpoint paths below are relative to this base URL.
Get Quote
Get available car types and prices for a transfer. Use this to show pricing to your customers before they book.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| 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 (default: 1). Used to recommend the right car. |
| 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. |
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" }'
{
"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..."
}
}
Create Booking
Create a confirmed transfer booking. This creates a real reservation — only call after your customer confirms.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| 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 |
| passengers | number | optional | Number of passengers (default: 1) |
| suitcases | number | optional | Number of suitcases (default: 1) |
| car_type | string | optional | Car type from the quote (e.g. "Saloon", "People Carrier"). Auto-selected if omitted. |
| door_number | string | conditional | House/building number. Required when destination is a postcode (e.g. "12", "Flat 3"). |
| flight_number | string | conditional | Flight number for airport transfers (e.g. "BA2534"). Enables flight tracking. |
| 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") |
flight_number for airport transfers, cruise_name for port transfers, door_number when destination is a postcode.
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": "[email protected]", "door_number": "10", "flight_number": "BA2534", "special_requests": "Child seat needed" }'
{
"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": "[email protected]"
},
"duration": "51 minutes",
"meeting_point": {
"name": "Heathrow T5",
"instructions": "Our driver will hold a board with your name inside the terminal..."
},
"message": "Booking confirmed."
}
Response Fields
| Field | Type | Description |
|---|---|---|
| booking_ref | string | APL internal booking reference (e.g. "APL-X7K9M2") |
| external_ref | number | Reservation ID in the dispatch system |
| status | string | Booking status — "confirmed" on success |
| price_gbp | number | Final price in GBP |
| meeting_point | object | Driver meeting instructions (for airport/station pickups) |
Car Types
Available vehicle types returned in quote responses. Use the car_type value when creating a booking.
| Car Type | Max Passengers | Max Bags | Description |
|---|---|---|---|
| Saloon | 3 | 3 | Standard sedan — ideal for 1–3 passengers |
| People Carrier | 5 | 5 | Spacious MPV for families or groups |
| 8 Seater | 8 | 8 | Minibus for larger groups |
| Executive Saloon | 3 | 3 | Premium sedan with luxury interior |
| Executive MPV | 7 | 7 | Premium people carrier |
| Executive 8 Seater | 8 | 8 | Premium minibus with luxury interior |
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.
Endpoint
https://mcp.airport-pickups-london.com/mcp
Authentication
The MCP server supports two authentication methods:
- API Key — Send your key in the
x-api-keyheader (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:
- Go to Settings → Integrations → Add Custom Integration
- Enter:
https://mcp.airport-pickups-london.com/mcp - Ask Claude: “How much is a taxi from Heathrow to Oxford?”
Claude Desktop
Add to your claude_desktop_config.json:
{
"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)
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.
MCP Tools
Two tools are available via the MCP server:
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.
| Parameter | Type | Required | Description |
|---|---|---|---|
origin | string | Yes | Pickup location — airport name or address/postcode |
destination | string | Yes | Dropoff location — address, postcode, or airport |
passengers | number | No | Number of passengers (default 1) |
suitcases | number | No | Number of suitcases (default 1) |
transfer_date | string | No | Date in YYYY-MM-DD format |
transfer_time | string | No | Time in HH:MM format |
book_london_airport_transfer
Create a confirmed reservation. Requires passenger details, date/time, and locations. Returns a booking reference and management link for payment and live driver tracking.
| Parameter | Type | Required | Description |
|---|---|---|---|
origin | string | Yes | Pickup location |
destination | string | Yes | Dropoff location |
transfer_date | string | Yes | Date (YYYY-MM-DD) |
transfer_time | string | Yes | Time (HH:MM) |
passenger_name | string | Yes | Full name |
passenger_phone | string | Yes | Phone with country code |
passenger_email | string | No | Email for confirmation |
passengers | number | No | Number of passengers (default 1) |
car_type | string | No | e.g. “Saloon”, “People Carrier” |
flight_number | string | No | Flight number for airport pickups |
special_requests | string | No | e.g. “child seat needed” |
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.
/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
- Discovery — Your agent fetches
/.well-known/agent.jsonto learn what APL can do - Authentication — Include your API key in the
x-api-keyheader (same key as the REST API) - Send a message — POST a JSON-RPC 2.0 request to
/a2awith amessage/sendmethod - 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 ID | Name | Description |
|---|---|---|
| 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
Returns the Agent Card describing APL's capabilities, skills, and authentication requirements. No API key required.
curl https://mcp.airport-pickups-london.com/.well-known/agent.json
Returns a JSON Agent Card with:
name— Agent identifier (airport-pickups-london)supported_interfaces— A2A endpoint URL and protocol versionskills— Available skills with descriptions, tags, and examplessecurity_schemes— How to authenticate (API key inx-api-keyheader)capabilities— Supported features (streaming, push notifications)
message/send
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
| State | Meaning |
|---|---|
| completed | Skill executed successfully — check artifacts for results |
| failed | Skill execution failed — check status.message for error details |
| input-required | Agent 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.
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" } }] } } }'
{
"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 }
]
}
}]
}]
}
}
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": "[email protected]", "passengers": 2, "car_type": "Saloon", "flight_number": "BA2534", "door_number": "10" } }] } } }'
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 tocreate_booking - Has
origin/destination? → routes toget_quote
tasks/get
Retrieve a previously created task by its ID. Tasks are stored in memory for 1 hour.
{
"jsonrpc": "2.0",
"id": 4,
"method": "tasks/get",
"params": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}
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
Cancel a task that is still in progress. Only tasks in submitted, working, or input-required states can be canceled.
{
"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
}
| Code | Name | Meaning |
|---|---|---|
| -32700 | Parse Error | Invalid JSON in request body |
| -32600 | Invalid Request | Missing jsonrpc: "2.0" or method |
| -32601 | Method Not Found | Unknown method (only message/send, tasks/get, tasks/cancel supported) |
| -32602 | Invalid Params | Missing or invalid parameters |
| -32603 | Internal Error | Server-side error |
| -32000 | Unauthorized | Missing or invalid API key |
| -32001 | Task Not Found | Task ID does not exist or has expired (1hr TTL) |
| -32002 | Task Not Cancelable | Task is already completed, failed, or canceled |
Agent Registration
- Email: [email protected]
- Phone: 020 3988 2168
- WhatsApp: +44 7365 268 656
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.
Public endpoint — no authentication needed. Rate limited to 3 registrations per IP per hour.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Your agent or company name |
email | string | Yes | Contact email (used for duplicate detection) |
url | string | No | Your website URL |
Example Request
{
"name": "TravelBot AI",
"email": "[email protected]",
"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."
}
/api/quote, /api/book), A2A protocol (/a2a), and MCP (/mcp).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"
}
| Status | Meaning | Common Causes |
|---|---|---|
| 400 | Bad Request | Missing/invalid fields, location not found, no vehicles available |
| 401 | Unauthorized | Missing or invalid API key |
| 429 | Rate Limited | Too many requests — max 60/minute per IP |
| 500 | Server Error | Internal error — please retry or contact support |
Typical Integration Flow
- Get a quote — Call
POST /api/quotewith pickup, dropoff and date/time - Show options — Display available car types and prices to your customer
- Collect details — Gather passenger name, phone, email, flight number (if airport), and door number (if postcode destination)
- Create booking — Call
POST /api/bookwith all details and the chosen car type - Confirm to customer — Share the
booking_refandmeeting_pointinstructions 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
Support
For API integration support, account setup, or technical issues:
- Email: [email protected]
- Phone: +44 208 688 7744 (24 hours)
- WhatsApp: +44 7538 989360