Biklo for developersTESTsandbox-api.biklo.comchange

Set your delivery bands

PUT/v1/company/shipping-absorption

scope company.write

Replaces the whole set for one country, scope AND parcel_tier. parcel_tier is REQUIRED: each destination carries two independent sets and writing one does not touch the other, so a default would quietly rewrite the small-parcel bands while you believed you had set both. Bands are half-open [min, max): a band's max_amount must EQUAL the next band's min_amount — writing 49999 then 50000 leaves a one-cent hole and the set is refused. The first band starts at 0, the last has max_amount: null. Amounts are in minor units. An empty bands array means you absorb delivery on everything.

Request body#

FieldTypeRequiredDescription
country_codestringoptionalThe DESTINATION this set applies to, as ISO-2. Omit it to write the scope's default set, used for every destination with no set of its own. Must be a country you sell into (country_not_supported, 422) — see GET /v1/company/selling-countries.
scopestringoptionalDefaults to local. The origin is always your own country, so this is decided by the destination: same country is local, anywhere else is international. They behave nothing alike — a domestic parcel is a few lei, a cross-border one can cost more than the product.

Accepts local · international

parcel_tierstringrequiredWhich size of parcel this set covers. small is accessories and small parcels; large is bikes and large or extra-large parcels. Each destination has a SEPARATE set per tier, so writing one leaves the other exactly as it was — absorbing delivery on a 300-lei accessory is a very different promise from absorbing it on a bike. Missing gives parcel_tier_required (422), an unknown value invalid_parcel_tier (422).

Accepts small · large

currencystringoptionalWhich currency the band amounts are in. Defaults to the currency already on the set.
bandsarrayrequiredThe complete ladder, which REPLACES whatever was there — this is not a merge. Required (field_required, 400). Rejections come back as invalid_bands (422) with every reason listed at once rather than one per round trip.
bands[].min_amountintegeroptionalWhere the band starts, in minor units, INCLUSIVE. Defaults to 0. The first band must start at 0, and each band must start exactly where the previous one ended — a gap and an overlap are the same mistake and get the same message.
bands[].max_amountintegeroptionalWhere the band ends, EXCLUSIVE — an order at exactly this amount falls into the next band. null means no upper limit, which only the LAST band may have, and the last band must have it. A band must end above where it starts.
bands[].absorbsbooleanoptionalWhether YOU pay the delivery for orders in this band. Defaults to false, which means the buyer pays it at checkout. Absorption is also capped at what the order earns you: on an order where the delivery would exceed that, the buyer is charged regardless of what this says.

Example

{
    "country_code": "ES",
    "scope": "local",
    "parcel_tier": "large",
    "currency": "EUR",
    "bands": [
        {
            "min_amount": 0,
            "max_amount": 50000,
            "absorbs": false
        },
        {
            "min_amount": 50000,
            "max_amount": null,
            "absorbs": true
        }
    ]
}

Response#

Returns the same object as Read your delivery bands (GET /v1/company/shipping-absorption), described in full there.

Example

{
    "sets": [
        {
            "country_code": "HU",
            "scope": "international",
            "parcel_tier": "small",
            "currency": "EUR",
            "bands": [
                {
                    "min_amount": 0,
                    "max_amount": 50000,
                    "absorbs": false
                },
                {
                    "min_amount": 50000,
                    "max_amount": null,
                    "absorbs": true
                }
            ]
        },
        {
            "country_code": "HU",
            "scope": "international",
            "parcel_tier": "large",
            "currency": "EUR",
            "bands": [
                {
                    "min_amount": 0,
                    "max_amount": null,
                    "absorbs": false
                }
            ]
        }
    ],
    "parcel_tiers": {
        "small": "Accessories and small parcels — billed on the small-courier tariff.",
        "large": "Bikes, large and extra-large items — the expensive tariff."
    },
    "note": "Bands compare the seller-group subtotal, in minor units. A band with absorbs=false means the buyer pays delivery at checkout. Each destination has a SEPARATE set per parcel_tier — writing one does not touch the other.",
    "band_rules": {
        "bands_are_half_open": "Each band covers [min_amount, max_amount) — max is exclusive.",
        "must_be_contiguous": "A band's max_amount must equal the next band's min_amount. Not max-1.",
        "first_band_starts_at_zero": true,
        "last_band_is_open_ended": "The last band must have max_amount: null.",
        "example": {
            "country_code": "RO",
            "parcel_tier": "small",
            "currency": "RON",
            "bands": [
                {
                    "min_amount": 0,
                    "max_amount": 50000,
                    "absorbs": false
                },
                {
                    "min_amount": 50000,
                    "max_amount": null,
                    "absorbs": true
                }
            ]
        }
    },
    "selling_countries": [
        {
            "country_id": 70,
            "code": "ES",
            "name": "España",
            "currency": "EUR"
        }
    ]
}

Failures use the shared error envelope — a machine-readable code and a request_id to quote to support. Error handling.

curl -X PUT "https://sandbox-api.biklo.com/v1/company/shipping-absorption" \
  -H "Authorization: Bearer bk_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "country_code": "ES",
    "scope": "local",
    "parcel_tier": "large",
    "currency": "EUR",
    "bands": [
        {
            "min_amount": 0,
            "max_amount": 50000,
            "absorbs": false
        },
        {
            "min_amount": 50000,
            "max_amount": null,
            "absorbs": true
        }
    ]
}'
<?php

$ch = curl_init('https://sandbox-api.biklo.com/v1/company/shipping-absorption');

curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer bk_test_YOUR_KEY',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode([
      'country_code' => 'ES',
      'scope' => 'local',
      'parcel_tier' => 'large',
      'currency' => 'EUR',
      'bands' => [
        0 => [
          'min_amount' => 0,
          'max_amount' => 50000,
          'absorbs' => false,
        ],
        1 => [
          'min_amount' => 50000,
          'max_amount' => NULL,
          'absorbs' => true,
        ],
      ],
    ]),
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);
using System.Net.Http;
using System.Net.Http.Headers;

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "bk_test_YOUR_KEY");

var request = new HttpRequestMessage(
    new HttpMethod("PUT"),
    "https://sandbox-api.biklo.com/v1/company/shipping-absorption");

request.Content = new StringContent(
    @"{ ""country_code"": ""ES"", ""scope"": ""local"", ""parcel_tier"": ""large"", ""currency"": ""EUR"", ""bands"": [ { ""min_amount"": 0, ""max_amount"": 50000, ""absorbs"": false }, { ""min_amount"": 50000, ""max_amount"": null, ""absorbs"": true } ] }",
    System.Text.Encoding.UTF8,
    "application/json");

var response = await client.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
import requests

response = requests.put(
    "https://sandbox-api.biklo.com/v1/company/shipping-absorption",
    headers={"Authorization": "Bearer bk_test_YOUR_KEY"},
    json={
        "country_code": "ES",
        "scope": "local",
        "parcel_tier": "large",
        "currency": "EUR",
        "bands": [
            {
                "min_amount": 0,
                "max_amount": 50000,
                "absorbs": False
            },
            {
                "min_amount": 50000,
                "max_amount": None,
                "absorbs": True
            }
        ]
    },
)

data = response.json()
const response = await fetch("https://sandbox-api.biklo.com/v1/company/shipping-absorption", {
  method: "PUT",
  headers: {
    Authorization: "Bearer bk_test_YOUR_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "country_code": "ES",
      "scope": "local",
      "parcel_tier": "large",
      "currency": "EUR",
      "bands": [
          {
              "min_amount": 0,
              "max_amount": 50000,
              "absorbs": false
          },
          {
              "min_amount": 50000,
              "max_amount": null,
              "absorbs": true
          }
      ]
  })
});

const data = await response.json();
import java.net.http.*;
import java.net.URI;

var client = HttpClient.newHttpClient();

var request = HttpRequest.newBuilder()
    .uri(URI.create("https://sandbox-api.biklo.com/v1/company/shipping-absorption"))
    .header("Authorization", "Bearer bk_test_YOUR_KEY")
    .header("Content-Type", "application/json")
    .method("PUT", HttpRequest.BodyPublishers.ofString(
        "{ \"country_code\": \"ES\", \"scope\": \"local\", \"parcel_tier\": \"large\", \"currency\": \"EUR\", \"bands\": [ { \"min_amount\": 0, \"max_amount\": 50000, \"absorbs\": false }, { \"min_amount\": 50000, \"max_amount\": null, \"absorbs\": true } ] }"))
    .build();

var response = client.send(request, HttpResponse.BodyHandlers.ofString());