Biklo for developersTESTsandbox-api.biklo.comchange

Addresses and locations

Every address is country → county → city, plus a street and a postal code. A courier rejects the shipment if any part is wrong, so it is worth getting right at the point where your user types it, not at the point where we reject the order.

Your own address comes first#

The chain below is what you resolve in order to create one thing: your shipping address. The default one is where the courier collects, and it is what a listing's location is copied from when you publish a product without a city_id.

curl "https://sandbox-api.biklo.com/v1/addresses" -H "Authorization: Bearer $KEY"

An empty list is the problem worth catching early. Products publish without an address, look correct, and then the first order has no origin and cannot be fulfilled. Create one with POST /v1/addresses, and move the default with POST /v1/addresses/{id}/default.

Buyer addresses are not your concern — they arrive on the order, already validated. What follows is for your addresses and for any address form you put in front of your own users.

Resolving the chain#

curl "https://sandbox-api.biklo.com/v1/geo/countries" -H "Authorization: Bearer $KEY"
curl "https://sandbox-api.biklo.com/v1/geo/counties?country=RO" -H "Authorization: Bearer $KEY"
curl "https://sandbox-api.biklo.com/v1/geo/cities?country=RO&q=craio" -H "Authorization: Bearer $KEY"

The city table holds 727 000 rows, so GET /v1/geo/cities requires a filter — country, county_id or q — and pages by cursor. An unfiltered request returns 400 filter_required rather than trying to serve the table.

Search matches both scripts. q=Sofia finds София, because Bulgarian cities are stored in Cyrillic and nobody types that into an ERP.

Validate before you send#

curl "https://sandbox-api.biklo.com/v1/geo/address-rules?country=RO" -H "Authorization: Bearer $KEY"
{
  "street": { "min_length": 5, "max_length": 50, "must_contain_digit": true },
  "postal_code": { "pattern": "/^\\d{6}$/", "example": "500123", "validated_by_county_prefix": true },
  "required_fields": ["country_code", "county_id", "city_id", "address", "postal_code"]
}

These are the rules we actually enforce, published rather than described, so they cannot drift from what we apply. Run them in your own form and your user fixes the address while they are still looking at it.

The street must contain a number. It is the single most common reason a courier cannot deliver.

Postal codes are suggestions, never a gate#

curl https://sandbox-api.biklo.com/v1/geo/cities/1 -H "Authorization: Bearer $KEY"

That returns the postal codes we know for the city — use them for autofill and suggestions.

Do not reject a code because it is missing from that list. We measured it: roughly 7.5% of real, valid Romanian postal codes are absent from the source data. Validating by set-membership would have blocked hundreds of genuine addresses. Validate by format, and by county prefix where validated_by_county_prefix is true.