Welcome to the comobi json api documentation

General info

Base url

The base url of the Comobi api is https://api.comobi.be

For testing purposes you can use https://api.staging.comobi.be

You can go to https://kompasplein.be/login and login using the username and password we provided to see the result of your api calls.

Authentication

Each call to an endpoint of the Comobi api will require a Brearer Token as authentication method. The api doesn’t have a login functionality, so this token can only be acquired by contacting us.

Status codes

200 Successful request

201 Successfully created

401 Unauthorized

404 Not found; The specified order was not found

422 Unprocessable Entity; The body failed the validation requirements

429 Too Many Requests; More requests than the rate limit allows (60/min)

500 Internal server error

Error responses

All errors are returned as JSON, regardless of the request's Accept header. A 422 response lists the violated rules per field:

{
    "message": "The po field is required. (and 2 more errors)",
    "errors": {
        "po": ["The po field is required."],
        "travel_agency_name": ["The travel agency name field is required."],
        "passengers": ["The passengers field is required."]
    }
}

A 401 response returns {"error": "Invalid bearer token"}.

Formatting

All timestamps should use the ISO 8601 standard and are formatted as string(20) using the combined date and time format. All timestamps should be in UTC.
Example: 2026-11-15T06:28:00Z

Text lengths

A field of type STRING(n) accepts at most n characters. A longer value is refused with a 422 response that names the field.

Airport codes

Currently we only accept the following aiport codes for the departure_airport_code and return_airport_code fields:
AMS, ANR, BRU, CRL, CDG, DUS, EIN, LGG, LIL, OST, ZYR, XDB, XFA, LUX, CGN, GRQ, MST, ORY, RTM and FBN
This restriction does not apply to the destination_airport_code field. That field accepts any airport code of at most 183 characters.

Orders

Create an order

Method: POST

Endpoint: /orders/create

JSON body:

FIELD OPTIONAL REQUIRED IF TYPE DESCRIPTION
po × STRING(191) The unique identifier for an order
travel_agency_name × STRING(191) The travel agency’s name
travel_agency_license × STRING(191) The travel agency’s unique license number
travel_agency_phone × STRING(191) The travel agency’s phone number
travel_agency_email × STRING(191) The travel agency’s email address
departure_date ✓ if departure_flight or departure_airport_code is set DATETIME The departure flights departure date (must be in the future)
departure_flight ✓ if departure_date or departure_airport_code is set STRING(191) The departure flight code
departure_airport_code ✓ if departure_date or departure_flight is set STRING The departure airport code (possible values: AMS, ANR, BRU, CRL, CDG, DUS, EIN, LGG, LIL, OST, ZYR, XDB, XFA, LUX, CGN, GRQ, MST, ORY, RTM and FBN)
checkin ✓ INT Preferred minutes in airport before flight, between 0 and 1440 (default 120)
return_date ✓ if return_flight or return_airport_code is set DATETIME The return flights arrival date (must be in the future)
return_flight ✓ if return_date or return_airport_code is set STRING(191) The return flight code
return_airport_code ✓ if return_date or return_flight is set STRING The return airport code (possible values: AMS, ANR, BRU, CRL, CDG, DUS, EIN, LGG, LIL, OST, ZYR, XDB, XFA, LUX, CGN, GRQ, MST, ORY, RTM and FBN)
destination_airport_code ✓ STRING(183) The travel destination airport code
passengers × ARRAY[INT] Array with the ages of the passengers (preferably on the date of departure). This data is only used to calculate the amount of passengers an the amount of childseats that the driver should bring.
cargo ✓ ARRAY[CARGO] Array with the cargo models (see cargo for more info)
suitcases ✓ INT The amount of suitcases (defaults to the amount of passengers)
client_firstname ✓ STRING(191) The client’s firstname
client_name ✓ STRING(191) The client’s name
client_email ✓ if client_language is set STRING(191) The client’s email
client_phone ✓ STRING(191) The client’s phone number
client_language ✓ STRING The client’s language (possible values: null, nl, en or fr)
client_street ✓ if client_street_nr or client_city is set STRING(191) The client's address street name.
client_street_nr ✓ if client_street or client_city is set STRING(191) The client's address street number.
client_zip ✓ if client_street or client_street_nr or client_city or client_country_code is set STRING(191) The client's address zip.
client_city ✓ if client_street or client_street_nr is set STRING(191) The client's address city.
client_country_code ✓ no STRING The client's address country as an ISO 3166-1 alpha-2 code (BE, NL, FR, ...). Absent, the country follows client_zip: four digits is BE, four digits and two letters is NL, and any other zip stores the address with no country (NULL). Present, a client_zip that does not match the format of that country is refused with a 422: BE four digits, NL four digits, a space and two letters, FR five digits.
comments ✓ STRING Extra comments about the order

Examples:

There are a lot of different possibilities to create an order. in the best case scenario all values are set:


{
    "po": "po_test",
    "travel_agency_name": "test",
    "travel_agency_license": "123456",
    "travel_agency_phone": "32412345678",
    "travel_agency_email": "info@example.com",
    "departure_date": "2023-05-23T08:00:00Z",
    "departure_flight": "TB1234",
    "departure_airport_code": "CRL",
    "return_date": "2023-06-01T08:00:00Z",
    "return_flight": "TB1234",
    "return_airport_code": "BRU",
    "destination_airport_code": "TST",
    "passengers": [
        35,31,8,4,1,0
    ],
    "suitcases": 2,
    "client_firstname": "fname",
    "client_name": "name",
    "client_email": "fname.name@example.com",
    "client_phone": "324912345678",
    "client_language": "nl",
    "client_street": "street",
    "client_street_nr": "1",
    "client_zip": "1000",
    "client_city": "Brussels",
    "cargo":[
        {
            "name": "Wheelchair",
            "amount": 1
        },
        {
            "name": "Golfbag",
            "amount": 2
        }
    ],
    "comments": "This is a test comment"
}

It's possible to create orders with only a departure transfer. In this case you can just leave the return_date, return_flight and return_airport_code out of the body.


{
    "po": "po_test",
    "travel_agency_name": "test",
    "travel_agency_license": "123456",
    "travel_agency_phone": "32412345678",
    "travel_agency_email": "info@example.com",
    "departure_date": "2023-05-23T08:00:00Z",
    "departure_flight": "TB1234",
    "departure_airport_code": "CRL",
    "destination_airport_code": "TST",
    "passengers": [
        35,31,8,4,1,0
    ],
    "suitcases": 2,
    "client_firstname": "fname",
    "client_name": "name",
    "client_email": "fname.name@example.com",
    "client_phone": "324912345678",
    "client_language": "nl",
    "client_street": "street",
    "client_street_nr": "1",
    "client_zip": "1000",
    "client_city": "Brussels",
    "cargo":[
        {
            "name": "Wheelchair",
            "amount": 1
        },
        {
            "name": "Golfbag",
            "amount": 2
        }
    ],
    "comments": "This is a test comment"
}

Or the other way around, only a return transfer. In this case you can just leave the departure_date, departure_flight and departure_airport_code out of the body.


{
    "po": "po_test",
    "travel_agency_name": "test",
    "travel_agency_license": "123456",
    "travel_agency_phone": "32412345678",
    "travel_agency_email": "info@example.com",
    "destination_airport_code": "TST",
    "return_date": "2023-06-01T08:00:00Z",
    "return_flight": "TB1234",
    "return_airport_code": "BRU",
    "passengers": [
        35,31,8,4,1,0
    ],
    "suitcases": 2,
    "client_firstname": "fname",
    "client_name": "name",
    "client_email": "fname.name@example.com",
    "client_phone": "324912345678",
    "client_language": "nl",
    "client_street": "street",
    "client_street_nr": "1",
    "client_zip": "1000",
    "client_city": "Brussels",
    "cargo":[
        {
            "name": "Wheelchair",
            "amount": 1
        },
        {
            "name": "Golfbag",
            "amount": 2
        }
    ],
    "comments": "This is a test comment"
}

O>As shown above the destination_airport_code, client_firstname, client_name, client_email, client_phone, client_language, client_street, client_street_nr, client_zip and client_city are optional. Leaving any of these fields empty will result in an "open order". This means the travel agency will have to add this data manually to our platform.


{
    "po": "po_test",
    "travel_agency_name": "test",
    "travel_agency_license": "123456",
    "travel_agency_phone": "32412345678",
    "travel_agency_email": "info@example.com",
    "departure_date": "2023-05-23T08:00:00Z",
    "departure_flight": "TB1234",
    "departure_airport_code": "CRL",
    "return_date": "2023-06-01T08:00:00Z",
    "return_flight": "TB1234",
    "return_airport_code": "BRU",
    "passengers": [
        35,31,8,4,1,0
    ],
    "suitcases": 2,
    "cargo":[
        {
            "name": "Wheelchair",
            "amount": 1
        },
        {
            "name": "Golfbag",
            "amount": 2
        }
    ],
    "comments": "This is a test comment"
}

Update

Method: PUT

Endpoint: /orders/{po}/update

A cancelled order cannot be updated. The request is refused with a 422 response: {"errors": "The order is cancelled, so updating it is not possible."}. In this response errors is a string, not the per-field object of the validation errors above. After a cancellation, every API request on that PO is refused: a create returns 422 "The po is already being used.", an update and a delete return the 422 described here and under Delete. To bring the cancelled order back, ask Comobi to restore it. For a new booking, use a new PO.

JSON body:

FIELD OPTIONAL REQUIRED IF TYPE DESCRIPTION
travel_agency_name ✓ STRING(191) The travel agency’s name
travel_agency_license ✓ STRING(191) The travel agency’s unique license number
travel_agency_phone ✓ STRING(191) The travel agency’s phone number
travel_agency_email ✓ STRING(191) The travel agency’s email address
departure_date ✓ if departure_flight or departure_airport_code is set DATETIME The departure flights departure date (must be in the future)
departure_flight ✓ if departure_date or departure_airport_code is set STRING(191) The departure flight code
departure_airport_code ✓ if departure_date or departure_flight is set STRING The departure airport code (possible values: AMS, ANR, BRU, CRL, CDG, DUS, EIN, LGG, LIL, OST, ZYR, XDB, XFA, LUX, CGN, GRQ, MST, ORY, RTM and FBN)
checkin ✓ INT Preferred minutes in airport before flight, between 0 and 1440 (default 120)
return_date ✓ if return_flight or return_airport_code is set DATETIME The return flights arrival date (must be in the future)
return_flight ✓ if return_date or return_airport_code is set STRING(191) The return flight code
return_airport_code ✓ if return_date or return_flight is set STRING The return airport code (possible values: AMS, ANR, BRU, CRL, CDG, DUS, EIN, LGG, LIL, OST, ZYR, XDB, XFA, LUX, CGN, GRQ, MST, ORY, RTM and FBN)
destination_airport_code ✓ STRING(183) The travel destination airport code
passengers ✓ ARRAY[INT] Array with the ages of the passengers (preferably on the date of departure). This data is only used to calculate the amount of passengers an the amount of childseats that the driver should bring.
cargo ✓ ARRAY[CARGO] Array with the cargo models (see cargo for more info)
suitcases ✓ INT The amount of suitcases (defaults to the amount of passengers)
client_firstname ✓ STRING(191) The client’s firstname
client_name ✓ STRING(191) The client’s name
client_email ✓ if client_language is set STRING(191) The client’s email
client_phone ✓ STRING(191) The client’s phone number
client_language ✓ STRING The client’s language (possible values: null, nl, en or fr)
client_street ✓ if client_street_nr or client_zip or client_city is set STRING(191) The client's address street name
client_street_nr ✓ if client_street or client_zip or client_city is set STRING(191) The client's address street number
client_zip ✓ if client_street or client_street_nr or client_city or client_country_code is set STRING(191) The client's address zip
client_city ✓ if client_street or client_street_nr or client_zip is set STRING(191) The client's address city
client_country_code ✓ STRING The client's address country as an ISO 3166-1 alpha-2 code (BE, NL, FR, ...). Send it together with the address: client_zip is required when it is set. Absent, the country follows client_zip: four digits is BE, four digits and two letters is NL, and any other zip stores the address with no country (NULL). Present, a client_zip that does not match the format of that country is refused with a 422: BE four digits, NL four digits, a space and two letters, FR five digits. An update without address fields keeps the stored country.
comments ✓ STRING Extra comments about the order

Examples:


{
    "departure_date": "2023-01-24T06:00:00Z",
    "departure_flight": "TB1234",
    "departure_airport_code": "BRU"
}

If you set the the departure_date, departure_flight, departure_airport_code, return_date, return_flight and return_airport_code when creating the order, you can remove a transfer by sending a requests with null for the transfer values. (If the values are left out of the request, the transfer will not be deleted, but alse not updated):

Delete

Method: DELETE

Endpoint: /orders/{po}/delete

A delete cancels the order. A cancelled order cannot be deleted again. The request is refused with a 422 response: {"errors": "The order is already cancelled, so deleting it again is not possible."}. An archived order cannot be deleted either: 422 {"errors": "The order is already archived, so deleting it is no longer possible."}. In both responses errors is a string. To bring a cancelled order back, ask Comobi to restore it.

For TUI-VIP the delete endpoint is not available: the request is refused with a 451 response, and the attempt is recorded on the order.

Open orders

This endpoint returns all orders where we still require extra info. To become an active order, the client info (client_* fields) and destination_airport_code must be filled in.
The created_at field is the moment the order was booked.
All get routes are paginated. You can change the page using the page URL parameter and the amount of records using the per_page URL parameter (100 by default, max 5000).

Method: GET

Endpoint: /orders/open

Response example:


{
    "data": [
        {
            "po": "po_test",
            "travel_agency_name": "test",
            "travel_agency_license": "123456",
            "travel_agency_phone": "32412345678",
            "travel_agency_email": "info@example.com",
            "departure_date": "2026-11-22T06:28:00Z",
            "departure_flight": "TB1234",
            "departure_airport_code": "BRU",
            "checkin": 180,
            "return_date": "2026-11-29T06:28:00Z",
            "return_flight": "TB1234",
            "return_airport_code": "BRU",
            "destination_airport_code": "TST",
            "cargo": [
                {
                    "name": "WHC",
                    "amount": 1
                }
            ],
            "suitcases": 6,
            "client_firstname": "fname",
            "client_name": "name",
            "client_email": "fname.name@example.com",
            "client_phone": "324912345678",
            "client_language": "nl",
            "client_street": null,
            "client_street_nr": null,
            "client_zip": null,
            "client_city": null,
            "client_country_code": null,
            "comments": [],
            "created_at": "2022-10-10T09:50:55.000000Z"
        },
        ...
    ],
    "links": {
        "first": "https:/api.staging.comobi.be/orders/open?page=1",
        "last": "https:/api.staging.comobi.be/orders/open?page=3",
        "prev": null,
        "next": "https:/api.staging.comobi.be/orders/open?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "path": "https://api.staging.comobi.be/orders/open",
        "per_page": 100,
        "to": 100,
        "total": 256
    }
}

Active orders

This endpoint returns the active orders. These orders are ready to be processed, but still have a transfer in the future.
The created_at field is the moment the order was booked.
All get routes are paginated. You can change the page using the page URL parameter and the amount of records using the per_page URL parameter (100 by default, max 5000).

Method: GET

Endpoint: /orders/active

Response example:


{
    "data": [
        {
            "po": "po_test",
            "travel_agency_name": "test",
            "travel_agency_license": "123456",
            "travel_agency_phone": "32412345678",
            "travel_agency_email": "info@example.com",
            "departure_date": "2026-11-22T06:28:00Z",
            "departure_flight": "TB1234",
            "departure_airport_code": "BRU",
            "checkin": 180,
            "return_date": "2026-11-29T06:28:00Z",
            "return_flight": "TB1234",
            "return_airport_code": "BRU",
            "destination_airport_code": "TST",
            "cargo": [
                {
                    "name": "WHC",
                    "amount": 1
                }
            ],
            "suitcases": 6,
            "client_firstname": "fname",
            "client_name": "name",
            "client_email": "fname.name@example.com",
            "client_phone": "324912345678",
            "client_language": "nl",
            "client_street": "street",
            "client_street_nr": "1",
            "client_zip": "1000",
            "client_city": "Brussels",
            "client_country_code": "BE",
            "comments": [],
            "created_at": "2022-10-10T09:50:55.000000Z"
        },
        ...
    ],
    "links": {
        "first": "https:/api.staging.comobi.be/orders/archived?page=1",
        "last": "https:/api.staging.comobi.be/orders/archived?page=3",
        "prev": null,
        "next": "https:/api.staging.comobi.be/orders/archived?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "path": "https://api.staging.comobi.be/orders/archived",
        "per_page": 100,
        "to": 100,
        "total": 256
    }
}

Archived orders

This endpoint returns the archived orders. These orders happened in the past or were cancelled. A cancelled order will have the deleted_at field filled in. Archived orders also contain a price if they weren't cancelled.
The created_at field is the moment the order was booked.
All get routes are paginated. You can change the page using the page URL parameter and the amount of records using the per_page URL parameter (100 by default, max 5000).

Method: GET

Endpoint: /orders/archived

Response example:


{
    "data": [
        {
            "po": "po_test",
            "travel_agency_name": "test",
            "travel_agency_license": "123456",
            "travel_agency_phone": "32412345678",
            "travel_agency_email": "info@example.com",
            "departure_date": "2026-11-22T06:28:00Z",
            "departure_flight": "TB1234",
            "departure_airport_code": "BRU",
            "checkin": 180,
            "return_date": "2026-11-29T06:28:00Z",
            "return_flight": "TB1234",
            "return_airport_code": "BRU",
            "destination_airport_code": "TST",
            "cargo": [
                {
                    "name": "WHC",
                    "amount": 1
                }
            ],
            "suitcases": 6,
            "client_firstname": "fname",
            "client_name": "name",
            "client_email": "fname.name@example.com",
            "client_phone": "324912345678",
            "client_language": "nl",
            "client_street": "street",
            "client_street_nr": "1",
            "client_zip": "1000",
            "client_city": "Brussels",
            "client_country_code": "BE",
            "comments": [],
            "created_at": "2022-10-10T09:50:55.000000Z",
            "deleted_at": null,
            "price": 150
        },
        ...
    ],
    "links": {
        "first": "https:/api.staging.comobi.be/orders/archived?page=1",
        "last": "https:/api.staging.comobi.be/orders/archived?page=3",
        "prev": null,
        "next": "https:/api.staging.comobi.be/orders/archived?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "path": "https:/api.staging.comobi.be/orders/archived",
        "per_page": 100,
        "to": 100
    }
}

Cargo

FIELD OPTIONAL TYPE DESCRIPTION
name × STRING The cargo’s name
amount × INT Amount of the cargo

Example:


{
    “name”: “Golfbag”,
    “amount”: 3
}