{
  "openapi": "3.1.0",
  "info": {
    "title": "Worldway Travel Commerce API",
    "version": "1.0.0",
    "description": "Search flights and tours, check live tour availability, quote tours and plan trips. All prices are live and Worldway-branded. Authenticate with an API key issued by Worldway (header `X-Api-Key: wwk_live_…`) or a partner user's access token (`Authorization: Bearer …`, plus `X-Worldway-Tenant` if the user belongs to several partners). Each partner has a per-minute rate limit; every call is logged against the partner.",
    "contact": {
      "name": "Worldway Travels Group",
      "url": "https://worldwaytravelsgroup.com"
    }
  },
  "servers": [
    {
      "url": "https://worldwaytravelsgroup.com/api/v1",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Commerce"
    }
  ],
  "paths": {
    "/commerce/search-flights": {
      "post": {
        "operationId": "searchFlights",
        "summary": "Search flights",
        "description": "Requires scope `flights.search`. Read-only — no booking or payment is made through the API.",
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "origin",
                  "destination",
                  "depart_date"
                ],
                "properties": {
                  "origin": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 60,
                    "example": "DEL"
                  },
                  "destination": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 60,
                    "example": "BOM"
                  },
                  "depart_date": {
                    "type": "string",
                    "format": "date",
                    "example": "2026-12-15"
                  },
                  "return_date": {
                    "type": "string",
                    "format": "date",
                    "example": "2026-12-15"
                  },
                  "passengers": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9,
                    "default": 1
                  },
                  "cabin": {
                    "type": "string",
                    "enum": [
                      "economy",
                      "premium_economy",
                      "business",
                      "first"
                    ],
                    "default": "economy"
                  }
                }
              },
              "example": {
                "origin": "DEL",
                "destination": "BOM",
                "depart_date": "2026-12-15",
                "passengers": 1,
                "cabin": "economy"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Success"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing JSON body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope, tenant suspended, or account not a partner member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Request valid but could not be fulfilled (e.g. no live availability)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded for this partner",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait"
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/commerce/search-tours": {
      "post": {
        "operationId": "searchTours",
        "summary": "Search tours",
        "description": "Requires scope `tours.read`. Read-only — no booking or payment is made through the API.",
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "city": {
                    "type": "string",
                    "maxLength": 60
                  },
                  "country": {
                    "type": "string",
                    "maxLength": 60
                  },
                  "duration": {
                    "type": "string",
                    "enum": [
                      "day",
                      "2-4",
                      "5-8",
                      "9+"
                    ]
                  },
                  "page": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 50,
                    "default": 1
                  }
                }
              },
              "example": {
                "country": "Italy",
                "duration": "day",
                "page": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Success"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing JSON body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope, tenant suspended, or account not a partner member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Request valid but could not be fulfilled (e.g. no live availability)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded for this partner",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait"
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/commerce/tour-availability": {
      "post": {
        "operationId": "tourAvailability",
        "summary": "Live tour availability",
        "description": "Requires scope `tours.read`. Read-only — no booking or payment is made through the API.",
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tour_id",
                  "from_date",
                  "travellers"
                ],
                "properties": {
                  "tour_id": {
                    "type": "string",
                    "pattern": "^[\\w-]{2,200}$"
                  },
                  "from_date": {
                    "type": "string",
                    "format": "date",
                    "example": "2026-12-15"
                  },
                  "travellers": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 40
                  }
                }
              },
              "example": {
                "tour_id": "rome-colosseum-tour",
                "from_date": "2026-12-15",
                "travellers": 2
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Success"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing JSON body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope, tenant suspended, or account not a partner member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Request valid but could not be fulfilled (e.g. no live availability)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded for this partner",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait"
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/commerce/quote-tour": {
      "post": {
        "operationId": "quoteTour",
        "summary": "Quote a tour",
        "description": "Requires scope `tours.quote`. Read-only — no booking or payment is made through the API.",
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tour_id",
                  "date",
                  "service",
                  "adults"
                ],
                "properties": {
                  "tour_id": {
                    "type": "string"
                  },
                  "date": {
                    "type": "string",
                    "format": "date",
                    "example": "2026-12-15"
                  },
                  "service": {
                    "type": "string",
                    "enum": [
                      "regular",
                      "private"
                    ]
                  },
                  "adults": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 40
                  },
                  "children": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 20,
                    "default": 0
                  },
                  "infants": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 10,
                    "default": 0
                  }
                }
              },
              "example": {
                "tour_id": "rome-colosseum-tour",
                "date": "2026-12-15",
                "service": "regular",
                "adults": 2
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Success"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing JSON body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope, tenant suspended, or account not a partner member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Request valid but could not be fulfilled (e.g. no live availability)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded for this partner",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait"
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/commerce/plan-trip": {
      "post": {
        "operationId": "planTrip",
        "summary": "Plan a trip (flights + tour)",
        "description": "Requires scope `trips.plan`. Read-only — no booking or payment is made through the API.",
        "security": [
          {
            "ApiKey": []
          },
          {
            "BearerToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "origin",
                  "destination",
                  "depart_date",
                  "return_date",
                  "adults"
                ],
                "properties": {
                  "origin": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 60,
                    "example": "DEL"
                  },
                  "destination": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 60,
                    "example": "FCO"
                  },
                  "depart_date": {
                    "type": "string",
                    "format": "date",
                    "example": "2026-12-15"
                  },
                  "return_date": {
                    "type": "string",
                    "format": "date",
                    "example": "2026-12-20"
                  },
                  "adults": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9
                  },
                  "children": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 8,
                    "default": 0
                  },
                  "tour_ref": {
                    "type": "string"
                  },
                  "tour_query": {
                    "type": "string",
                    "maxLength": 80
                  }
                }
              },
              "example": {
                "origin": "DEL",
                "destination": "FCO",
                "depart_date": "2026-12-15",
                "return_date": "2026-12-20",
                "adults": 2
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Success"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or missing JSON body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope, tenant suspended, or account not a partner member",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Request valid but could not be fulfilled (e.g. no live availability)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded for this partner",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait"
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {},
  "x-webhooks-status": "Outbound partner webhooks are not offered yet. All operations are synchronous request/response; no events are pushed to partners.",
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key",
        "description": "Partner API key (wwk_live_…). Shown once at creation; store it securely."
      },
      "BearerToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Partner API key or partner user access token."
      }
    },
    "schemas": {
      "Success": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "data": {
            "type": "object"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string"
          }
        },
        "example": {
          "error": "Missing scope tours.quote"
        }
      }
    }
  }
}