NAV
bash php

Introduction

Welcome to the Budbee API!

This document contains information about endpoints that you may use to manage orders in our system.

Prerequisites

There are three mandatory steps required to create each order:

  1. Validate Delivery Postalcode
  2. Request Upcoming Intervals
  3. Post a valid order

Failure to complete any of these tasks may result in erronous input which would be ignored by the API.

When an order is created it is considered a complete booking and will be performed unless it is cancelled.

If you use a Transport Administration system, like Unifaun Online you must add Parcel information to the Order (the Shipping label) before we collect the parcel.
This is so our automatic terminals can scan the parcels and route it to the correct distribution vehicle.
Failure to append Parcel information will result in a cancelled order.

Available Integrations

Our API has been integrated into several existing e-commerce stores and Transport Administration systems.
If you find what you use here, you may not need to do any development at all.

API Client Link
PHP Github
TMS System Link
Unifaun Online www.unifaun.com
Unifaun Apport www.unifaun.com
Logtrade www.logtrade.se
Centiro www.centiro.se
Consignor www.consignor.se
Ingrid www.ingrid.com
Webshipper www.webshipper.com
Paazl www.paazl.com
Transsmart www.transsmart.com
Metapack www.metapack.com
Pakketpartner www.pakketpartner.nl
E-commerce platforms Link
Askås www.askas.se
E37 www.e37.se
Carismar www.carismar.com
Unifaun Delivery Checkout www.unifaun.com
Logtrade Delivery Checkout www.logtrade.se
Ingrid Checkout Widget www.ingrid.com
Paazl Delivery Checkout www.paazl.com
Kodmyran www.kodmyran.se
Vendre www.vendre.se
Woocommerce krokedil.se/budbee

Authentication

To authorize, use this code:

curl --user apiKey:apiSecret "api_endpoint_here"
require_once('vendor/autoload.php');

$api = new \Budbee\Client("apiKey", "apiSecret", Budbee\Client::$SANDBOX);
$postalCodesAPI = new \Budbee\PostalcodesApi($api);
$intervalAPI = new \Budbee\IntervalApi($api);
$orderAPI = new \Budbee\OrderApi($api);

Make sure to replace apiKey and apiSecret with your API key and secret key.

An API user connects to the API via TLS (HTTPS) and authenticates with Basic Authentication. Budbee generates public and private keys for each API users, one set of keys for the sandbox and one set for the production environment.

Use the API Key as username and API Secret as password in the Basic Authentication

Authorization: Basic base64_encode(apiKey:apiSecret)

Environment URL
Sandbox https://sandbox.api.budbee.com
Production https://api.budbee.com

Sender Addresses

Sender Addresses are the registered locations where Budbee will pickup the Merchants parcels.

Get all Sender Addresses

curl "https://api.budbee.com/users/collection-points"
  --user apiKey:apiSecret
  -H "Accept: application/vnd.budbee.users-v1+json"
  -H "Content-Type: application/vnd.budbee.users-v1+json"

The above command returns JSON structured like this:

[
  {
    "id": 2672,
    "name": "Merchant Warehouse",
    "referencePerson": "John Doe",
    "telephoneNumber": "+46700000000",
    "address": {
      "id": 8793,
      "street": "Sender Street 1",
      "postalCode": "16353",
      "city": "Stockholm",
      "country": "SE"
    },
    "doorCode": "",
    "outsideDoor": false,
    "defaultCollectionPoint": true
  },
  {
    "id": 7313,
    "name": "Merchant Warehouse 2",
    "referencePerson": "Jane Doe",
    "telephoneNumber": "+46700000000",
    "address": {
      "id": 8797,
      "street": "Sender Street 2",
      "postalCode": "40010",
      "city": "Göteborg",
      "country": "SE"
    },
    "doorCode": "",
    "outsideDoor": false,
    "defaultCollectionPoint": false
  }
]

This endpoint retrieves all Sender addresses

HTTP Request

GET https://api.budbee.com/users/collection-points

Delivery Postalcode Validation

Before orders are created, it is crucial that the delivery postalcode is validated. Failure to do so may result in the order not being created.

Validate Postalcode

curl "https://api.budbee.com/postalcodes/validate/SE/11453"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.postalcodes-v2+json"
    -H "Content-Type: application/vnd.budbee.postalcodes-v2+json"
try {
    $possibleCollectionPoints = $postalCodesAPI->checkPostalCode('SE', '11453');
} catch (\Budbee\Exception\BudbeeException $e) {
    die('Budbee does not deliver to specified Postal Code');
}

The above command will generate a JSON array containing the Sender addresses that this Delivery postalcode may be used in conjuction with when creating an order:

[
  {
    "id": 2672,
    "name": "Merchant Warehouse",
    "referencePerson": "John Doe",
    "telephoneNumber": "+46700000000",
    "address": {
      "id": 8793,
      "street": "Sender Streeet 1",
      "postalCode": "16353",
      "city": "Stockholm",
      "country": "SE"
    },
    "doorCode": "",
    "outsideDoor": false,
    "defaultCollectionPoint": true
  }
]

You may display and select Budbee as a Shipping option if the recipients postal code is within the Budbee Delivery Area.

This endpoint returns either 200 OK (Postal code is within Delivery Area) or 404 Not Found (Postal code is outside of Delivery Area)

Additionally, the response body contains the Merchants sender addresses that is applicable for this Delivery postal code.
If there are different sender addresses per country (E.g Sweden and Finland) you may use this result to decide what sender address to use.

HTTP Request

GET https://api.budbee.com/postalcodes/validate/{countryCode}/{postalCode}

Status Codes

Code Description
200 Budbee performs deliveries in this Postal Code
404 Postal Code is invalid

Path parameters

Parameter Type Description
countryCode String Recipient Country code ISO 3166-1 alpha-2 e.g. “SE”
postalCode String The delivery Postalcode to validate

Postal Code list

curl "https://api.budbee.com/postalcodes/SE"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.postalcodes-v1+json"
    -H "Content-Type: application/vnd.budbee.postalcodes-v1+json"

The above command returns a JSON array containing all valid postalcodes that Budbee performs deliveries in.

[
    "10012",
    "10026",
    "10027",
    "10028",
    "10029",
    "10031",
    "10040"
]

This endpoint retrieves all postalcodes that Budbee performs deliveries in, separated by Country.

HTTP Request

GET https://api.budbee.com/postalcodes/{countryCode}

Path parameters

Parameter Type Description
countryCode String Recipient Country code ISO 3166-1 alpha-2 e.g. “SE”

Estimated Delivery Date

You may display an estimated Delivery time for recipients in the Checkout. We will return our estimates based on the deadlines you have for pick-and-pack.

Get Upcoming Delivery Windows

This endpoint will retrieve upcoming delivery windows for a specific delivery postalcode.

We use Unix epoch time in milliseconds, and the timezone we return is always in UTC (GMT+0)

curl "https://api.budbee.com/intervals/SE/11453/1"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.intervals-v2+json"
    -H "Content-Type: application/vnd.budbee.intervals-v2+json"
try {
    $intervalResponse = $intervalAPI->getIntervals('SE', '11453', 1);
} catch (\Budbee\Exception\BudbeeException $e) {
    die('No upcoming delivery intervals');
}

$firstInterval = $intervalResponse[0];
$interval = new \Budbee\Model\OrderInterval($firstInterval->collection, $firstInterval->delivery);
$collectionPointId = $firstInterval->collectionPointId;

echo 'Estimated Delivery Date: ' + $interval->delivery->start + ' and ' + $interval->delivery->stop;

The above command will retrieve 1 upcoming interval for the postalcode 11453:

[
  {
    "collection": {
      "start": 1479880800000,
      "stop": 1479916800000
    },
    "delivery": {
      "start": 1479884400000,
      "stop": 1479916800000
    },
    "collectionPointIds": [
      2
    ]
  }
]
curl "https://api.budbee.com/intervals/SE/11453/2016-12-01/2016-12-02"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.intervals-v2+json"
    -H "Content-Type: application/vnd.budbee.intervals-v2+json"

The above command will retrieve intervals between 2016-12-01 and 2016-12-02 for postalcode 11453:

[
  {
    "collection": {
      "start": 1480572000000,
      "stop": 1480608000000
    },
    "delivery": {
      "start": 1480575600000,
      "stop": 1480608000000
    },
    "collectionPointIds": [
      2
    ]
  },
  {
    "collection": {
      "start": 1480658400000,
      "stop": 1480712400000
    },
    "delivery": {
      "start": 1480687200000,
      "stop": 1480712400000
    },
    "collectionPointIds": [
      2
    ]
  }
]

HTTP Request

GET https://api.budbee.com/intervals/{countryCode}/{postalCode}/{n}
GET https://api.budbee.com/intervals/{countryCode}/{postalCode}/{toDate}
GET https://api.budbee.com/intervals/{countryCode}/{postalCode}/{fromDate}/{toDate}

Status Codes

Code Description
200 OK, body contains list of Intervals
404 Postal Code is invalid or no Intervals are available

Path parameters

Parameter Type Description
countryCode String Recipient Country code ISO 3166-1 alpha-2 e.g. “SE”
n Integer Number of intervals to request (limit 20)
toDate Date Intervals up to and including a date (YYYY-MM-DD)
fromDate Date Intervals from and including a date (YYYY-MM-DD)

Orders

To create an order you need to populate these required fields:

Each object is described in detail below

Objects

Cart

The cart consists of a mandatory cartId that should be a unique identifier describing the purchase in your e-commerce store. Most e-commerce softwares call this “order number”.

Field Type Max len. Optional Description
cartId string 255 false The sales order number from your e-commerce software

Delivery

The delivery object describes the consumer and delivery address for an order.
You may at any time update the consumer information, but you may never update the delivery address on an order. To change either delivery address or interval see Update Interval or Address

Field Type Max len. Optional Description
name string 255 false Name of the recipient, e.g “John Doe” or “Company Ltd.”
referencePerson string 255 true Reference person of the recipient, e.g. “John Doe”
socialSecurityNumber string 255 true Social Security Number of the recipient
telephoneNumber string 255 false The telephone number of recipient, prefferably mobile phone
email string 255 true The email of the recipient
address Address N/A false See Address
doorCode string 255 true Doorcode
outsideDoor boolean N/A false Is it ok to leave shipment outside door if recipient is not at home
additionalInfo string N/A true Additional info to us and/or driver regarding shipment

Address

Field Type Max len. Optional Description
street string 255 false Street name and number of address
street2 string 255 true Street name two, e.g. apartment number
postalCode string 255 false Postalcode
city string 255 false City
country string 2 false Country code ISO 3166-1 alpha-2 e.g. “SE”
{
    "name": "<string>",
    "referencePerson": "<string>",
    "socialSecurityNumber": "<string>",
    "telephoneNumber": "<string>",
    "email": "<string>",
    "address": {
        "street": "<string>",
        "street2": "<string>",
        "postalCode": "<string>",
        "city": "<string>",
        "country": "<string>"
    },
    "doorCode": "<string>",
    "outsideDoor": <boolean>,
    "additionalInfo": "<string>"
}

Additional Services

additionalServices defines extra settings available for each order, such as identification checking, if the recipient must be the same as the end customer etc.

Field Default value Description
identificationCheckRequired false Driver must check identification at delivery
recipientMinimumAge 0 The recipient must be at least this old at delivery
recipientMustMatchEndCustomer false The recipient must be the same person that booked the order
numberOfMissRetries null Number of times that a failed delivery may be retried until returned to your Warehouse (null for infinite)
{
    "identificationCheckRequired": <boolean>,
    "recipientMinimumAge": <integer>,
    "recipientMustMatchEndCustomer": <boolean>,
    "numberOfMissRetries": <integer>
}

Parcels

Parcels have a shipment number (unique per order/shipment) and a package number (unique per parcel).
Parcels may also have optional Dimensions.

If you supply empty values in either shipmentId or packageId we will generate values for you.

Field Type Max len. Optional Description
shipmentId string 255 true The shipment number (Must be unique per shipment/order)
packageId string 255 true The package number (Must be unique per Parcel)
dimensions Dimensions N/A true Dimensions of Parcel
{
    "shipmentId": "<string>",
    "packageId": "<string>",
    "dimensions": {
        "width": <integer of width in cm>,
        "height": <integer of height in cm>,
        "length": <integer of length in cm>,
        "weight": <integer of weight in grams>,
        "volume": <integer of volume in cm3>
    }
}

Dimensions

Field Type Description
width int Width in centimeters
height int Height in centimeters
length int Length in centimeters
weight int Weight in gram
volume int Volume in cubic centimeters (cm3)

Create Order

You must perform all required steps above before creating an order. All required fields in an order must exist.

If order is created we return 200 OK along with the created order in the body.

You must handle the response in case of error

Status Codes

Code Description
200 Order created
400 Bad Request – Your request is wrong
401 Unauthorized – Your API key is wrong
403 Forbidden – One or more fields you have supplied have invalid values
422 Validation Error. You have supplied something that cannot be parsed
500 Internal Server Error – We had a problem with our server. Try again later.
502 Service Unavailable – We’re temporarially offline for maintanance. Please try again later.
503 Service Unavailable – We’re temporarially offline for maintanance. Please try again later.
curl "https://api.budbee.com/multiple/orders"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.multiple.orders-v2+json"
    -H "Content-Type: application/vnd.budbee.multiple.orders-v2+json"
    -X POST -d
{
  "collectionId": 2672,
  "cart": {
    "cartId": "0000001"
  },
  "delivery": {
    "name": "John Doe",
    "referencePerson": null,
    "socialSecurityNumber": "19891109-8690"
    "telephoneNumber": "+46700000000",
    "email": "john.doe@budbee.com",
    "address": {
      "street": "Grevgatan 9",
      "street2": "LGH 1601",
      "postalCode": "11453",
      "city": "Stockholm",
      "country": "SE"
    },
    "doorCode": "1337",
    "outsideDoor": true,
    "additionalInfo": "I live on the 6th floor"
  },
  "requireSignature": false,
  "additionalServices": {
      "identificationCheckRequired": false,
      "recipientMinimumAge": 0,
      "recipientMustMatchEndCustomer": false,
      "numberOfMissRetries": null
  }
}

Set delivery date

Set the delivery date of an Order by supplying a valid value generated by the Estimated Delivery Date endpoint.

The input will be validated, and rejected if not valid / has expired.

curl "https://api.budbee.com/multiple/orders"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.multiple.orders-v2+json"
    -H "Content-Type: application/vnd.budbee.multiple.orders-v2+json"
    -X POST -d
{
  "interval": {
    "delivery": {
      "start": 1556636400000,
      "stop": 1556654400000
    }
  },
  "collectionId": 2672,
  "cart": {
    "cartId": "0000001"
  },
  "delivery": {
    "name": "John Doe",
    "referencePerson": null,
    "socialSecurityNumber": "19891109-8690"
    "telephoneNumber": "+46700000000",
    "email": "john.doe@budbee.com",
    "address": {
      "street": "Grevgatan 9",
      "street2": "LGH 1601",
      "postalCode": "11453",
      "city": "Stockholm",
      "country": "SE"
    },
    "doorCode": "1337",
    "outsideDoor": true,
    "additionalInfo": "I live on the 6th floor"
  },
  "requireSignature": false,
  "additionalServices": {
    "identificationCheckRequired": false,
    "recipientMinimumAge": 0,
    "recipientMustMatchEndCustomer": false,
    "numberOfMissRetries": null
  }
}

Retrieve a Specific Order

This will retrieve a specific order

curl "https://api.budbee.com/multiple/orders/e140396d-5679-4211-96f8-c6c877b43186"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.multiple.orders-v1+json"
    -H "Content-Type: application/vnd.budbee.multiple.orders-v1+json"
$order = $orderApi->get('e140396d-5679-4211-96f8-c6c877b43186');

HTTP Request

GET https://api.budbee.com/multiple/orders/{id}

Status Codes

Code Description
200 OK, body contains Order
404 Order not found

Path parameters

Parameter Type Description
id uuid The id of the order

Update Consumer information

This will update the information about the End Customer on an order.

curl "https://api.budbee.com/multiple/orders/e140396d-5679-4211-96f8-c6c877b43186"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.multiple.orders-v1+json"
    -H "Content-Type: application/vnd.budbee.multiple.orders-v1+json"
    -X PUT -d
{
    "name": "Jane Doe",
    "referencePerson": "John Doe",
    "socialSecurityNumber": "19900205-9146"
    "telephoneNumber": "+46700000001",
    "email": "jane.doe@budbee.com",
    "doorCode": "1337",
    "outsideDoor": true,
    "additionalInfo": "We moved to the 5th floor, its all downhill from here"
}
$order = $orderAPI->createOrder($data);
$deliveryContact = $order->delivery;
$deliveryContact->name = 'Jane Doe';
$deliveryContact->referencePerson = 'John Doe';
$deliveryContact->telephoneNumber = '+4670000001';
$deliveryContact->email = 'jane.doe@budbee.com';
$deliveryContact->additionalInfo = 'We moved to the 5th floor, its all downhill from here'

$updatedOrder = $orderAPI->editDeliveryContact($order->id, $deliveryContact);

HTTP Request

PUT https://api.budbee.com/multiple/orders/{id}

Status Codes

Code Description
200 OK, body contains updated Order
404 Order not found

Path parameters

Parameter Type Description
id uuid The id of the order

Update Delivery Date or Address

To change delivery address or date, cancel it and create a new order.

Cancel an Order

This will cancel an order. Once an order is cancelled, it can not be undone.

curl "https://api.budbee.com/multiple/orders/e140396d-5679-4211-96f8-c6c877b43186"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.multiple.orders-v1+json"
    -H "Content-Type: application/vnd.budbee.multiple.orders-v1+json"
    -X DELETE
$orderApi->removeOrder('e140396d-5679-4211-96f8-c6c877b43186');

HTTP Request

DELETE https://api.budbee.com/multiple/orders/{id}

Status Codes

Code Description
204 Order cancelled
403 Not allowed to cancel Order
404 Order not found

Path parameters

Parameter Type Description
id uuid The id of the order

Parcels

Add Parcels to an existing Order

You can populate multiple parcels per Order.

Either supply existing unique shipment number and package numbers in the respective shipmentId and packageId fields, or leave the fields blank and we will generate values for you.

curl "https://api.budbee.com/multiple/orders/e140396d-5679-4211-96f8-c6c877b43186/parcels"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.multiple.orders-v2+json"
    -H "Content-Type: application/vnd.budbee.multiple.orders-v2+json"
    -X POST -d
[
    {
        "shipmentId": "6178966427",
        "packageId": "373325380927798300",
        "dimensions": {
            "weight": 2400
        }
    }
]

The above request returns JSON structured like this:

[
    {
        "id": 123,
        "shipmentId": "6178966427",
        "packageId": "373325380927798300",
        "label": "https://api.budbee.com/orders/e140396d-5679-4211-96f8-c6c877b43186/373325380927798300/label"
    }
]

Leave blank values for Budbee generated ID’s:

curl "https://api.budbee.com/multiple/orders/e140396d-5679-4211-96f8-c6c877b43186/parcels"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.multiple.orders-v2+json"
    -H "Content-Type: application/vnd.budbee.multiple.orders-v2+json"
    -X POST -d
[
    {
        "shipmentId": "",
        "packageId": "",
        "dimensions": {
            "weight": 2400
        }
    }
]

The above request returns JSON structured like this:

[
    {
        "id": 123,
        "shipmentId": "73501099200000086",
        "packageId": "735010992000000082",
        "label": "https://api.budbee.com/orders/e140396d-5679-4211-96f8-c6c877b43186/735010992000000082/label"
    }
]

HTTP Request

POST https://api.budbee.com/multiple/orders/{id}/parcels
Accept: application/vnd.budbee.multiple.orders-v2+json

Status Codes

Code Description
200 Parcels created
404 Order not found

Path parameters

Parameter Type Description
id uuid The id of the order

Remove a Parcel

This will remove a Parcel from an Order. You can do this until the Parcel has been picked up by Budbee.

curl "https://api.budbee.com/multiple/orders/e140396d-5679-4211-96f8-c6c877b43186/parcels/123"
    --user apiKey:apiSecret
    -H "Accept: application/vnd.budbee.multiple.orders-v1+json"
    -H "Content-Type: application/vnd.budbee.multiple.orders-v1+json"
    -X DELETE

HTTP Request

DELETE https://api.budbee.com/multiple/orders/{id}/parcels/{parcelId}

Status Codes

Code Description
204 Deleted Parcel
403 Not allowed to delete Parcel
404 Parcel not found

Path parameters

Parameter Type Description
id uuid The id of the order
parcelId id The id of the parcel

Shipping Labels

In the response body of a Parcel there is a URI to a shipping label that can be printed.

The generated shipping label is a PDF file of 10x15cm, for other formats, supply any of these query parameters:

Parameter Values
fileType pdf, zpl
documentSize 10x15

ZPL label in 10x15cm
https://uri/label?fileFormat=zpl&size=10x15

Track & Trace

You may want to notify recipients about upcoming shipments with Budbee.

Recipients may only edit information about their shipment if the tracking link is authenticated and comes for a secure source. You can request such a link with the following resource.

This will retrieve a tracking link for a specific order. This will be the same link that we send to recipients from our service.

curl "https://api.budbee.com/multiple/orders/e140396d-5679-4211-96f8-c6c877b43186/tracking-url"
  --user apiKey:apiSecret
  -H "Accept: application/vnd.budbee.multiple.orders-v1+json"
  -H "Content-Type: application/vnd.budbee.multiple.orders-v1+json"

{
  "url": "https://bdb.ee/abc123"
}
curl "https://api.budbee.com/parcels/00373325381304831806/tracking-url"
  --user apiKey:apiSecret
  -H "Accept: application/vnd.budbee.parcels-v1+json"
  -H "Content-Type: application/vnd.budbee.parcels-v1+json"

{
  "url": "https://bdb.ee/abc123"
}

HTTP Request

GET https://api.budbee.com/multiple/orders/{id}/tracking-url
GET https://api.budbee.com/parcels/{packageId}/tracking-url

Path parameters

Parameter Type Description
id uuid The id of the order
Parameter Type Description
packageId string The package ID of the Parcel

Webhook Callbacks

You can subscribe to API Callbacks via Webhooks to get notified about events for Orders. Your webservice must respond with 200 OK for all webhooks. If the request fails (not 200 OK) we will retry 10 times, with 30 minute intervals. If the request still fails after that the Webhook will be deleted and you may re-subscribe to it once your webservice is functional.

You can subscribe to these different webhooks by either creating them via the API, or adding them manually through our web interface:

Type Explanation
Order Status Updates Updates on Order Statuses, including “On Route to Collection”, “Collected”, “On Route to Delivery”, “Delivered”
Misses Failed deliveries
Cancellations Cancelled Orders
Ratings Ratings on Orders left by End Customer
End Customer Edits Edits of End Customer information, like name and telephone number
Delivery Address Edits Edits of Delivery Address information, like doorcode
Order Settings Edits Edits of Order Settings, like outsideDoorOk

Security

We sign each request made to your service using the merchants Secret API key.
The signature (found in the X-Budbee-Signature header) is a SHA-1 HMAC hash of the request body.

Optionally you can also supply username/password credentials that we will attach in every request using Basic authentication (in the Authorization header). You can supply credentials when subscribing:

{ "url": "http://yourserver.com/callbacks/status-updates", "username": "foobar", "password": "letmein" }

HTTPS is recommended for webhooks.

Status Updates

Subscribe to Status Updates for Parcels

Available Statuses:

HTTP Request

POST https://api.budbee.com/webhooks/parcel-status-updates

curl "https://api.budbee.com/webhooks/parcel-status-updates"
    --user apiKey:apiSecret
  -H "Accept: application/json"
  -H "Content-Type: application/json"
    -X POST -d 
{
    "url": "http://yourserver.com/callbacks/status-updates"
}

This webhook callback will contain JSON that looks like this:

{
    "id": "d95bad19-9252-4143-9abe-27bfaccb42ad",
    "token": "onww1jr4",
    "date": 1474976376000,
    "status": "Delivered",
    "shipmentId": "6133911930",
    "packageId": "373325381317444680",
    "coordinate": {
      "latitude": 59.1234,
      "longitude": 18.1234
    }
}

Failed Deliveries

Subscribe to information about failed delivery attempts

HTTP Request

POST https://api.budbee.com/webhooks/misses

curl "https://api.budbee.com/webhooks/misses"
    --user apiKey:apiSecret
  -H "Accept: application/json"
  -H "Content-Type: application/json"
    -X POST -d 
{
    "url": "http://yourserver.com/callbacks/misses"
}

This webhook callback will contain JSON that looks like this:

{
    "id": "d95bad19-9252-4143-9abe-27bfaccb42ad",
    "token": "onww1jr4",
    "date": 1474976376000,
    "comment": "Could not get into building. Customer did not answer phone",
    "category": "other",
    "coordinate": {
      "latitude": 59.1234,
      "longitude": 18.1234
    }
}

Cancelled Orders

Subscribe to Order Cancellations (Order was cancelled by Budbee).
This happens when an Order should not be delivered anymore.

HTTP Request

POST https://api.budbee.com/webhooks/cancellations

curl "https://api.budbee.com/webhooks/cancellations"
    --user apiKey:apiSecret
  -H "Accept: application/json"
  -H "Content-Type: application/json"
    -X POST -d 
{
    "url": "http://yourserver.com/callbacks/cancellations"
}

This webhook callback will contain JSON that looks like this:

{
    "id": "d95bad19-9252-4143-9abe-27bfaccb42ad",
    "token": "onww1jr4",
    "date": 1474976376000,
    "comment": "This order should be returned to sender",
    "category": "OTHER",
    "coordinate": {
      "latitude": 59.1234,
      "longitude": 18.1234
    }
}

Cancelled Delivery attempts

Subscribe to Delivery Attempt Cancellations. A callback will be posted when a Delivery Attempt is cancelled.
This may happen when the delivery has been delayed, or it has been rebooked into a new delivery attempt

HTTP Request

POST https://api.budbee.com/webhooks/delivery-attempt-cancellations

curl "https://api.budbee.com/webhooks/delivery-attempt-cancellations"
  --user apiKey:apiSecret
  -H "Accept: application/json"
  -H "Content-Type: application/json"
  -X POST -d
{
    "url": "https://yourserver.com/callbacks/delivery-attempt-cancellations"
}

This webhook callback will contain JSON that looks like this:

{
    "id": "d95bad19-9252-4143-9abe-27bfaccb42ad",
    "token": "onww1jr4",
    "date": 1474976376000,
    "deliveryAttemptId": 589866,
    "collectionInterval": {
        "startTimestamp": {
            "date": 1479880800000,
            "timezone": "UTC"
        },
        "stopTimestamp": {
            "date": 1479916800000,
            "timezone": "UTC"
        }
    },
    "deliveryInterval": {
        "startTimestamp": {
            "date": 1479884400000,
            "timezone": "UTC"
        },
        "stopTimestamp": {
            "date": 1479916800000,
            "timezone": "UTC"
        }
    },
    "comment": "This delivery attempt has been cancelled",
    "category": "OTHER"
}

Consumer Reviews

Subscribe to reviews (consumer has left a review about a delivery)
Ratings has a score between 1-5, and an optional comment. If the consumer selected a score between 1-3 they must select a category describing the issue.

HTTP Request

POST https://api.budbee.com/webhooks/ratings

curl "https://api.budbee.com/webhooks/ratings"
  --user apiKey:apiSecret
  -H "Accept: application/json"
  -H "Content-Type: application/json"
  -X POST -d 
{
    "url": "http://yourserver.com/callbacks/ratings"
}

This webhook callback will contain JSON that looks like this:

{
    "id": "d95bad19-9252-4143-9abe-27bfaccb42ad",
    "token": "onww1jr4",
    "date": 1474976376000,
    "score": 5,
    "comment": "Super delivery!"
}

Or:

{
    "id": "d95bad19-9252-4143-9abe-27bfaccb42ad",
    "token": "onww1jr4",
    "date": 1474976376000,
    "score": 1,
    "comment": "Delivery was not good",
    "category": "time_of_arrival"
}

Edited Consumer

Subscribe to Consumer Edits (name, email, phonenumber)

HTTP Request

POST https://api.budbee.com/webhooks/end-customer-edits

curl "https://api.budbee.com/webhooks/end-customer-edits"
    --user apiKey:apiSecret
  -H "Accept: application/json"
  -H "Content-Type: application/json"
    -X POST -d 
{
    "url": "http://yourserver.com/callbacks/end-customer-edits"
}

This webhook callback will contain JSON that looks like this:

{
    "id": "d95bad19-9252-4143-9abe-27bfaccb42ad",
    "token": "onww1jr4",
    "date": 1474976376000,
    "previousEndCustomer": {
      "id": 1,
      "name": "John Doe",
      "referencePerson": null,
      "phoneNumber": "+001234567",
      "email": "john.doe@budbee.com",
      "comment": null
    },
    "newEndCustomer": {
      "id": 2,
      "name": "Jane Doe",
      "referencePerson": null,
      "phoneNumber": "+009876543",
      "email": "jane.doe@budbee.com",
      "comment": null
    }
}

Edited Delivery Address

Subscribe to Delivery Address Edits (e.g Door code)

HTTP Request

POST https://api.budbee.com/webhooks/delivery-address-edits

curl "https://api.budbee.com/webhooks/delivery-address-edits"
    --user apiKey:apiSecret
  -H "Accept: application/json"
  -H "Content-Type: application/json"
    -X POST -d 
{
    "url": "http://yourserver.com/callbacks/delivery-address-edits"
}

This webhook callback will contain JSON that looks like this:

{
    "id": "d95bad19-9252-4143-9abe-27bfaccb42ad",
    "token": "onww1jr4",
    "date": 1474976376000,
    "previousAddress": {
      "id": 1,
      "street": "Sandhamnsgatan 63C",
      "street2": null,
      "postalCode": "11528",
      "city": "Stockholm",
      "countryCode": "SE",
      "addressSettings": {
        "doorCode": "1234"
      }
    },
    "newAddress": {
      "id": 2,
      "street": "Sandhamnsgatan 63C",
      "street2": null,
      "postalCode": "11528",
      "city": "Stockholm",
      "countryCode": "SE",
      "addressSettings": {
        "doorCode": "1337"
      }
    }
}

Edited Order Settings

Subscribe to Order Settings Edits (Leave shipment outside door, require signature, require identification check)

HTTP Request

POST https://api.budbee.com/webhooks/order-settings-edits

curl "https://api.budbee.com/webhooks/order-settings-edits"
    --user apiKey:apiSecret
  -H "Accept: application/json"
  -H "Content-Type: application/json"
    -X POST -d 
{
    "url": "http://yourserver.com/callbacks/order-settings-edits"
}

This webhook callback will contain JSON that looks like this:

{
    "id": "d95bad19-9252-4143-9abe-27bfaccb42ad",
    "token": "onww1jr4",
    "date": 1474976376000,
    "previousSettings": {
      "id": 1,
      "outsideDoorOk": true,
      "signatureRequired": false,
      "identificationCheckRequired": false
    },
    "newSettings": {
      "id": 2,
      "outsideDoorOk": false,
      "signatureRequired": true,
      "identificationCheckRequired": true
    }
}

Widget

We offer a widget which you may embed on your product page to let consumers get a delivery estimate.
The widget will provide a fallback option of your choice if no time window is available for the consumer.

To use this widget you need add your domains to a whitelist in our merchant portal.

Setup widget

<script async src="https://widget.services.budbee.com/dist/load-1.0.js"></script>

First of all you need to load a script on your page. This script should be put either in the <head>-tag or in the end of <body>.

The script tag points to the script which loads the widget, and there are two environments you may use:

Environment URL
Production https://widget.services.budbee.com/dist/load-1.0.js
Sandbox https://widget.services.budbee.com/staging/dist/load-1.0.js

Initializing the widget

Static/Statically generated pages

<div
    class="budbee-delivery-widget"
    data-merchant-id="your-merchant-id" 
    data-locale="sv_SE"
    data-country="SE"
    data-prefill-postalcode="99999"
    data-fallback-carrier="Fallback carrier"
    data-fallback-time-window="1 - 3 days"
></div>

If you want to display the widget on a static page you just need to insert a DOM-element with your configuration set as data-attributes.

Dynamic pages

<div class="product-xxx">
    <div class="budbee-delivery-widget" />
</div>
<script>
window.budbeeLoaded = function (budbee) {
  // widget can be initiated as is and let it look for an element with the class .budbee-delivery-widget
  budbee.initDeliveryWidget();

  // you can expose the budbee instance and use it later/somewhere else
  window.budbee = budbee;

  // or by suppling an element and/or a config
  budbee.initDeliveryWidget(
    {
      element: document.querySelector('.product-xxx .budbee-delivery-widget'),
      config: {
        merchantId: 'your-merchant-id',
        locale: 'sv_SE',
        country: 'SE',
        fallbackCarrier: 'Fallback carrier',
        fallbackTimeWindow: '1 - 3 days'
      }
    },
    function (err, widget) {
      // If the page is an SPA, it should call dispose before routing to a new page.
      onProductPageLeave(function () {
        widget.dispose();
      });
    }
  );
}
</script>

If you have an SPA or dynamic webpage you probably want to load the widget yourself. It is important to load the script before you load your content, see setup.

When you define the window.budbeeLoaded-listener, the script will no longer try to automatically find and show a widget. It is up to you when and how you want to initialize the widget.

You can either let the configuration be made on the DOM-element and call budbee.initDeliveryWidget({ element: ... }), or you can specify the configuration when you load the widget.

If the page for example supports different languages, it can be helpful to expose the budbee variable if you want to supply different locales/update the configuration.

Custom timeWindow fetcher

If you’d like to dynamically fetch a delivery estimate as a fallback, you may supply a timewindowFetcher in the config. In that function you may call another external API to get a delivery estimate.

<script>
  window.budbeeLoaded = function (budbee) {
    budbee.initDeliveryWidget(
      {
        timeWindowFetcher: function (postalCode, done) {
          setTimeout(function () {
            done({
              name: 'Fallback carrier',
              timeWindow: '1 - 3 business days'
            })
          }, 3000);
        },
      },
      function (err, widget) {
      }
    );
  }
<script>

Events

The widget supplies one event, afterLookup, which tells if a postalCode lookup is successful or not. The event can be listen to via the widget instance return by calling initDeliveryWidget.

The callback returns an object of { success: Boolean }.

<script>
  window.budbeeLoaded = function (budbee) {
    budbee.initDeliveryWidget(
      function (err, widget) {
        if (err) {
          console.log(err);
          return;
        }

        widget.on('afterLookup', function (response) {
          console.log(response.success);
        });
      }
    );
  }
</script>

Methods

setTimeWindowFetcher(fn: Function): void

Supply a custom timeWindow-fetcher, see Custom timeWindow fetcher.

prefillPostalCode(postalCode: String): void

It tries to prefill the widget with a customer’s postal code. This might be useful if the customer is signed in to your shop and you’d like to prefill it for them. If the customer has already entered a postal code, then this call will be ignored.
The callback returns an object of { success: Boolean }.

dispose(): void

This method disposes the widget, removing it from the page and unregistering all hooks and events. If you’re running a Single-Page application then you want to call dispose before navigating from the current product page.

<script>
  window.budbeeLoaded = function (budbee) {
    budbee.initDeliveryWidget(
      function (err, widget) {
        if (err) {
          console.log(err);
          return;
        }

        widget.prefillPostalCode(99999, function (response) {
          console.log(response.success);
        });
      }
    );
  }
</script>

Widget sizing

The widget will change/animate the size of its <iframe> to be able to show content of different size.

It will try to fill its container full width at all times. So if you want to change the width or position of the widget, style the element which you are targeting when inserting the widget, and not the <iframe>.

Widget troubleshooting

403 forbidden

If a 403 Forbidden error is generated, that means that the domain trying to embed the widget is not whitelisted in the merchant portal.

{ message: null }

This probably means that a valid merchant id was not provided. See initializing or configuration to set the merchant id correctly.

Uncaught Error: only once instance of babel-polyfill is allowed

The script was loaded on the page more than one time. See setup

Widget configuration

The following are all the options you may pass to the widget.

data-merchant-id (merchantId)

The merchant id is used to identify which merchant uses the widget, and to see if the current domain is whitelisted for the merchant. eg. 11

data-locale (locale)

Set the locale that is used for translating text in the widget. String: sv_SE

data-country (contry)

Sets the county in which the postal code lookup is scoped to. String: SE

data-prefill-postalcode (prefillPostalcode)

Optional value that is used for trying to prefill the postalcode for the consumer. If there’s a conflict between the prefilled postalcode and the one that the consumer inserted, the consumer postalcode is used. String: 99999

data-fallback-carrier (fallbackCarrier)

If there’s no timewindow for a given postalcode lookup, a fallback might be used to provide an alternative shipping carrier. String: Your carrier

data-fallback-time-window (fallbackTimeWindow)

If the fallback carrier is supplied, a time window can be supplied to indicate when the consumer can expect their shipping. String: 1 - 3 days

data-collection-point-id (collectionPointId)

Optional. Specify from which collection point the parcels are collected from, to give the consumer an accurate estimate. Number