The My Flying Box (MFB) Web Service provides an interface to request shipment offers from multiple carriers in an homogenous way and place bookings for these offers.
By implementing this web service you will have access to a wide range of competitive rates without needing to implement other APIs, saving you time and money.
This documentation is meant for technical people implementing the MFB Web Service on their systems. It provides an exhaustive description of all exposed resources and the way to manipulate them, with corresponding code examples in several languages.
Please note that you can contact us at tech@myflyingbox.com if you need any help. We can also provide you with integration services if needed.
For direct use in your application and for example purposes, we also provide some client libraries for PHP, Prestashop and WooCommerce.
This column contains code examples for most features of the MFB Web Service.
Supported languages are listed on top of the column. You can dynamically switch depending on your needs.
We tried to make 'copy/paste'-friendly examples (for instance curl commands) to ease your development and testing process. Feel free to contact us at tech@myflyingbox.com with feedback or improvement suggestions.
Before diving into technical details, here is a summary of the general workflow of the web service. Items corresponding to a request to the webservice are linked to the corresponding section of the documentation; other items are actions to be performed on your side only.
When your account is registered on the web service, you will receive an ID and password for a test server only. You must use the test server to fully implement the web service. When your implementation is ready, contact us to obtain ID and password for the production server.
The MFB Web Service uses REST resources in a standardized way throughout the API. All request declarations are semantically meaningful:
At the moment we have no use for PUT, PATCH and DELETE requests.
The base URL for all your requests is the following : https://api.myflyingbox.com/v2
All the URIs below should be appended to the base URL.
You cannot use the MFB Web Service without authentication.
Authentication is stateless (there is no persistence), so you will need to include your credentials on every request.
Authentication is done through the
HTTP Basic Access Authentication
method.
curl https://api.myflyingbox.com/v2/ -u login:password
require 'net/http' # Or 'net/https' for ruby version < 2.0.0
uri = URI('https://api.myflyingbox.com/v2/quotes')
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
request = Net::HTTP::Get.new uri
request.request :basic_auth, 'login', 'password'
response = http.request request # Net::HTTPResponse object
end
{
"status":"failure",
"error":{
"type":"access_denied",
"message":"Unauthorized"
},
"self":"https://api.myflyingbox.com/v2"
}
failure
access_denied
Unauthorized
api.myflyingbox.com/v2/v2
All requests use the HTTP protocol.
Content must be encoded in UTF-8.
The web service supports two formats for passing request attributes:
Whatever format you use, make sure that the proper "content-type" header is used.
Check out the code example for quote requests for an example of curl requests using each format approach.
Responses are sent in JSON format.
Most programming languages include well supported JSON libraries, which you can use to manipulate the response data.
All text is encoded in UTF-8 character set. If your system is not using UTF-8, make sure that you use proper conversion methods for all interactions with the web service.
Responses are encapsulated in a basic envelop described below.
When sending a query to the MFB Web Service, you have access to three sources of information to interpret the success or failure of your request:
Please note that two other attributes are available for debugging purposes if you get query errors:
Below are presented the different HTTP response codes with corresponding error types. You can base your implementation on these codes.
{
"status":"failure",
"error":{
"type":"resource_not_found",
"message":"Quote not found"
},
"self":"https://api.myflyingbox.com/v2/quotes/3"
}
A quote contains a set of transportation offers. When requesting a new quote, you must send your shipment requirements (packages specifications, dates, shipper and recipient information) in the expected format (see 'Request parameters' below).
After you have received a quote, you can order any offer returned within this quote (see place an order below). Please note that when placing the order you cannot change the country or postal code of the shipper and recipient, and you cannot change the pack-list either. If you need to alter these details, you must request a new quote with the correct information.
Parameters must be encapsulated within a root element 'quote' (see code example on the right).
curl https://test.myflyingbox.com/v2/quotes -i -X POST -u {login}:{password} \
-H "Content-Type:application/json" \
-d '{"quote": {
"shipper": {
"country":"GB",
"postal_code": "SW1A 1AA",
"city": "London"
},
"recipient": {
"is_a_company": "false",
"country": "FR",
"postal_code": "31300",
"city": "Toulouse"
},
"parcels": [
{
"weight": 1,
"length": 60,
"width": 60,
"height": 40
},
{
"weight": 2.5,
"length": 30,
"width": 30,
"height": 20
}
]
}}'
curl https://test.myflyingbox.com/v2/quotes -i -X POST -u {login}:{password} \
-H "Content-Type:application/json" \
-d '{"quote": {
"shipper": {
"country":"GB",
"postal_code": "SW1A 1AA",
"city": "London"
},
"recipient": {
"is_a_company": "false",
"country": "FR",
"postal_code": "31300",
"city": "Toulouse"
},
"parcels": [
{
"weight": 1,
"length": 60,
"width": 60,
"height": 40
},
{
"weight": 2.5,
"length": 30,
"width": 30,
"height": 20
}
],
"offers_filters": {
"with_carrier_codes": ["ups"]
"without_product_codes": ["ups_access_point_standard"]
}
}}'
curl https://test.myflyingbox.com/v2/quotes -i -X POST -u {login}:{password} \
-d "quote[shipper][country]=GB" \
-d "quote[shipper][postal_code]=SW1A 1AA" \
-d "quote[shipper][city]=London" \
-d "quote[recipient][country]=FR" \
-d "quote[recipient][postal_code]=31300" \
-d "quote[recipient][city]=Toulouse" \
-d "quote[recipient][is_a_company]=false" \
-d "quote[parcels][][weight]=1" \
-d "quote[parcels][][length]=60" \
-d "quote[parcels][][width]=60" \
-d "quote[parcels][][height]=40" \
-d "quote[parcels][][weight]=2.5" \
-d "quote[parcels][][length]=30" \
-d "quote[parcels][][width]=30" \
-d "quote[parcels][][height]=20"
curl https://test.myflyingbox.com/v2/quotes -i -X POST -u {login}:{password} \
-H "Content-Type:application/json" \
-d '{
"quote": {
"parcel_type": "document",
"parcels": [
{
"type": "document",
"weight": 0.5
}
],
"recipient": {
"city": "Toulouse",
"country": "FR",
"is_a_company": false,
"postal_code": "31300"
},
"shipper": {
"city": "Nice",
"country": "FR",
"postal_code": "06000"
}
}
}'
{
"id": "2a4a628c-e541-4571-b817-a57cc3f89a1b",
"shipper": {
"postal_code": "AB1 6CC",
"country": "GB"
},
"recipient": {
"is_a_company": "true",
"postal_code": "06800",
"country": "FR"
},
"parcels": [
{
"weight": 3,
"length": 40,
"width": 30,
"height": 10,
},
{
"weight": 1.75,
"length": 50,
"width": 10,
"height": 10,
}
],
"offers": [
{
"id":"6d37b0ed-833d-4a59-9e57-d6bd7d935c9b",
"quote_id":"270cf4a5-e99f-45a5-9dca-1bf75cd3ca64",
"product_id":"732e50b7-ed0e-424a-8631-51c5135d2b23",
"product":{
"id":"732e50b7-ed0e-424a-8631-51c5135d2b23",
"carrier_code":"dhl",
"code":"dhl_worldwide_express",
"name":"Worldwide Express",
"delay":"24",
"pick_up":true,
"drop_off":false,
"preset_delivery_location":false
},
"price":{
"formatted":"€293.68",
"currency":"EUR",
"amount":293.68,
"amount_in_cents":29368
},
"price_vat":{
"formatted":"€57.56",
"currency":"EUR",
"amount":57.56,
"amount_in_cents":5756
},
"total_price":{
"formatted":"€351.24",
"currency":"EUR",
"amount":351.24,
"amount_in_cents":35124
},
"collection_dates":[
{
"date":"2013-11-14",
"cutoff":"If you book before 1pm on Thursday, or book up to a week in advance"
},
{
"date":"2013-11-15",
"cutoff":"If you book before 1pm on Friday, or book up to a week in advance"
},
{
"date":"2013-11-18",
"cutoff":"If you book before 1pm on Monday, or book up to a week in advance"
}
]
},
{
"id":"33a60039-ea0c-4855-b9aa-616690288a4a",
"quote_id":"270cf4a5-e99f-45a5-9dca-1bf75cd3ca64",
"product_id":"46dc8970-c48a-4420-a85c-6dd31becba00",
"product":{
"id":"46dc8970-c48a-4420-a85c-6dd31becba00",
"carrier_code":"dpd",
"code":"dpd_air_express",
"name":"Air Express",
"delay":"96",
"pick_up":true,
"drop_off":false,
"preset_delivery_location":false
},
"price":{
"formatted":"€240.74",
"currency":"EUR",
"amount":240.74,
"amount_in_cents":24074
},
"price_vat":{
"formatted":"€47.19",
"currency":"EUR",
"amount":47.19,
"amount_in_cents":4719
},
"total_price":{
"formatted":"€287.93",
"currency":"EUR",
"amount":287.93,
"amount_in_cents":28793
},
"collection_dates":[
{
"date":"2013-11-14",
"cutoff":"If you book before 1pm on Thursday, or book up to a week in advance"
},
{
"date":"2013-11-15",
"cutoff":"If you book before 1pm on Friday, or book up to a week in advance"
},
{
"date":"2013-11-18",
"cutoff":"If you book before 1pm on Monday, or book up to a week in advance"
}
]
}
]
}
An offer is proposed by a carrier with a price and some conditions. Offers are sold under MFB product names, with corresponding logos and several variants.
Offers returned by the web service cannot be accessed independently from the quote or order they are linked to; they are returned as a collection in quotes or as single objects in orders.
For offers where parcels are delivered at a predefined delivery location (as opposed to at-the-door delivery), the MFB Web Service gives you access to the list of predefined locations available for this offer.
To know which offers are concerned, you must check the offer's product attribute 'preset_delivery_location'. If set to true, the delivery will be done at a preset location, and not at the recipient's address.
To get the most relevant locations, you must pass a detailed address in your request. A set of available delivery locations will be returned, sorted by relevance (most relevant first).
The request will return a collection of locations. Each location has the following attributes:
For offers where parcels are dropped off at a predefined drop-off location (as opposed to a pickup), the MFB Web Service gives you access to the list of predefined locations available for this offer.
To know which offers are concerned, you must check the offer's product attribute 'drop_off'. If set to true, the collection can be done at a preset drop-off location, and not at the shipper's address.
To get the most relevant locations, you must pass a detailed address in your request. A set of available drop-off locations will be returned, sorted by relevance (most relevant first).
The request will return a collection of locations. Each location has the following attributes:
Creating an order object means that you are booking a transport on the basis of an offer and its corresponding quote attributes (collection and delivery postal codes and countries, pack-list). A successfully created order is contractually binding: you will be invoiced for all orders you created, on the basis of the final price transmitted by the carrier.
Parameters must be encapsulated within the root element 'order'.
Please note that the following data will be automatically retrieved from the original quote and cannot be changed while placing the order: postal code and country of the shipper and recipient, list of parcels and their characteristics. If you need to change these data, you must first request a new quote, and place a new order for the corresponding offer. You can use the product code of the offer to make sure that you order the same service as initially intended.
curl https://test.myflyingbox.com/v2/orders -i -X POST -u {login}:{password} \
-H "Content-Type:application/json" \
-d '{
"order": {
"offer_id": "b26115b4-1852-4937-be54-a65c510744bb",
"shipper": {
"name": "Lce Test collection",
"company": "MY FLYING BOX SAS",
"street": "15 route de France",
"state": "Alpes-Maritimes",
"phone": "+33622123613",
"email": "test@test.com"
},
"recipient": {
"name": "Lce Test delivery",
"company": "MY FLYING BOX SAS",
"street": "15 route de France",
"state": "Alpes-Maritimes",
"phone": "+33622123613",
"email": "test@test.com"
},
"parcels": [
{
"value": "15",
"currency": "EUR",
"description": "Books",
"shipper_reference": "4684-0770",
"recipient_reference": "AB-3072"
}
]
}
}'
curl https://test.myflyingbox.com/v2/orders -i -X POST -u {login}:{password} \
-H "Content-Type:application/json" \
-d '{
"order": {
"declare_customs_electronically": true,
"offer_id": "625d4079-f0dd-470f-bc37-31582ad14fd8",
"shipper": {
"company": "test",
"name": "test",
"street": "test",
"phone": "0123456789",
"email": "email@test.com",
"eori_number": "FR35819137589",
"vat_number": "FR35819137589",
"collection_date": "2024-09-05"
},
"recipient": {
"name": "test",
"street": "test",
"state": "NY",
"phone": "0123456789",
"email": "email@test.com",
"ein": "EIN123456"
},
"parcels": [
{
"description": "test",
"country_of_origin": "FR",
"value": "150.0",
"currency": "EUR"
}
],
"customs_details": {
"invoice_number": "INV312312",
"reason_for_export": "commercial",
"ship_price": 49.78,
"ship_currency": "EUR"
},
"customs_items": [
{
"description": "description article",
"customs_code": "4201003000",
"quantity": 1,
"currency_code": "EUR",
"mass_unit": "kg",
"country_of_origin": "FR",
"unit_value": 150.0,
"unit_weight": 3.0,
"value_currency": "EUR"
}
]
}
}'
{
"uuid": "1471b700-1c14-4076-ade5-861798844129",
"shipper": {
"name": "Lce Test collection",
"company": "MY FLYING BOX SAS",
"street": ["15 route de France"],
"city": "Cagnes-sur-Mer",
"state": "Alpes-Maritimes",
"postal_code": "AB1 6CC",
"phone": "+33622123613",
"country": "UK"
},
"recipient": {
"name": "Lce Test delivery",
"is_a_company": "true",
"company": "MY FLYING BOX SAS",
"street": ["15 route de France"],
"city": "Cagnes-sur-Mer",
"state": "Alpes-Maritimes",
"postal_code": "06800",
"phone": "+33622123613",
"country": "FR"
},
"parcels": [
{
"weight": '3',
"length": '40',
"width": '30',
"height": '10',
"value": "15",
"currency": "EUR",
"description": "Books",
"shipper_reference": "4684-0770",
"recipient_reference": "AB-3072"
},
{
"weight": '1.75',
"length": '50',
"width": '10',
"height": '10',
"value": "15",
"currency": "EUR",
"description": "Books",
"shipper_reference": "4684-0773",
"recipient_reference": "AB-3073"
}
]
}
After creating an order, in most cases, labels will need to be printed by the shipper and affixed on the parcels.
Labels are available almost immediately after placing the order, by sending a request to the URL specified below. The labels are returned in the form of a unique PDF file. When the order includes several parcels, or when more than one label needs to be printed, all relevant documents are included in the one PDF returned.
No parameters are expected in this request. Only the UUID of the order must be passed in the request URL.
A raw PDF file is returned in response to the request if the labels are available.
If for some reasons the labels are not yet available, you will receive a 404 status code and a generic error response, with error code labels_not_ready.
After an order is placed, you have immediate access to tracking information for all parcels.
No parameters are expected in this request. Only the UUID of the order must be passed in the request URL.
The response returns all event information for each parcel of this order, sorted in the same order as they were submitted when requesting the initial quote.
Please note that tracking information may vary from carrier to carrier. We forward it through our API in an homogenous way but with a lot of flexibility: many attributes are optional and when we get some non-standard information we try to forward it nevertheless. Make sure that your implementation fits this flexibility.
The root level ('data' node) contains an array of tracking information for each parcel. The attributes below correspond to one entry of the array. Check the example on the right for a complete response example.
curl https://test.myflyingbox.com/v2/orders/eb27ff8e-b353-4a3f-8e7e-69576e64ee1a/tracking \
-i -u {login}:{password}
{
"status":"success",
"self":"https://test.myflyingbox.com/v2/orders/eb27ff8e-b353-4a3f-8e7e-69576e64ee1a/tracking.json",
"data":[
{
"parcel_index":0,
"events":[
{
"code":"shipment_created",
"happened_at":"2013-12-10T11:26:23+01:00",
"label":{
"fr":"Expédition créée",
"en":"Shipment created"
}
},
{
"code":"picked_up",
"happened_at":"2013-12-11T11:24:00+01:00",
"label":{
"fr":"Paquet enlevé",
"en":"Package picked up"
},
"location":{
"city":"NICE CEDEX 3",
"postal_code":"06284",
"country":"FR"
}
},
{
"code":"in_transit",
"happened_at":"2013-12-12T03:43:00+01:00",
"label":{
"fr":"En transit",
"en":"In transit"
},
"location":{
"city":"ROISSY CHARLES DE GAULLE CEDEX",
"postal_code":"95702",
"country":"FR"
}
},
{
"code":"arrived_at_facility",
"happened_at":"2013-12-12T05:11:00+01:00",
"label":{
"fr":"Arrivé à la plateforme",
"en":"Arrived at hub"
},
"location":{
"city":"STANSTED",
"state":"ES",
"postal_code":"CM24",
"country":"GB"
}
},
{
"code":"delivery_in_progress",
"happened_at":"2013-12-12T10:39:00+01:00",
"label":{
"fr":"Livraison en cours",
"en":"Delivery in progress"
},
"location":{
"city":"ENFIELD",
"state":"MI",
"postal_code":"EN3",
"country":"GB"
}
},
{
"code":"delivery_exception",
"happened_at":"2013-12-12T11:48:00+01:00",
"label":{
"fr":"Problème de livraison",
"en":"Delivery exception"
},
"location":{
"city":"ENFIELD",
"state":"MI",
"postal_code":"EN3",
"country":"GB"
},
"details":{
"code":"not_available_or_closed",
"label":{
"fr":"Client non disponible ou entreprise fermée",
"en":"Customer not available or business closed"
}
}
}
]
}
]
}
If needed, after placing an order, you can cancel it. The order must still have the state "created".
No parameters are expected in this request. Only the UUID of the order must be passed in the request URL.
The response contains the order.
curl -X PUT https://test.myflyingbox.com/v2/orders/eb27ff8e-b353-4a3f-8e7e-69576e64ee1a/cancel \
-i -u {login}:{password}
Scheduling a pickup means that you are requesting the carrier to send a truck to collect your packages. This is only available for orders created with the 'delay_order flag'.
Parameters must be encapsulated within the root element 'pickup'.
This action combine and replace the quote creation and the order creation actions presented above. For this request, you will need to provide all the data and a way to sort and filter offers in one request. The first service matching your parameters will be selected and ordered.
Parameters must be encapsulated within the root element 'order'.
curl https://test.myflyingbox.com/v2/orders/automatic -i -X POST -u {login}:{password} \
-H "Content-Type:application/json" \
-d '{
"order": {
"shipper": {
"company": "test",
"name": "test",
"street" :"test",
"phone": "+33600000000",
"email": "support@myflyingbox.com",
"collection_date": "2022-10-20",
"country": "FR",
"postal_code": "31300",
"city": "Toulouse"
},
"recipient": {
"company": "test",
"name": "test",
"street": "test",
"phone": "+33600000000",
"email": "support@myflyingbox.com",
"country": "FR",
"postal_code": "06000",
"city": "Nice",
"is_a_company": "false"
},
"parcels": [
{
"description": "description",
"length": "15",
"height": "15",
"width": "15",
"weight": "1"
}
],
"offers_sort_attributes": {
"total_price": "asc"
},
"offers_filters": {
"with_preset_delivery_location": false,
"with_pick_up": true,
"with_drop_off": false,
"with_carrier_codes": ["dhl", "ups", "fedex"]
}
}
}'
Below are listed the latest changes made to the documentation, sorted by reverse chronological order (latest on top).