Расчёт стоимости и сроков
POST /v1/rates: параметры посылки, формат тарифов, типы доставки и условия списания запросов.
POST /v1/rates
Один вызов параллельно рассчитывает доставку всеми выбранными активными перевозчиками. При отсутствии carriers используются все активные интеграции.
| Поле | Тип | Правило |
|---|---|---|
| from / to | object | Обязательные адреса |
| from.city / to.city | string | Непустое название города |
| from.country / to.country | string | RU; по умолчанию RU |
| postal_code | string | null | Шесть цифр для РФ; нужен Почте России |
| parcel.weight_grams | integer | От 1 до 1 000 000 граммов |
| parcel.length_cm / width_cm / height_cm | number | Больше 0 и не больше 1 000 см |
| declared_value_kopecks | integer | От 0 до 100 000 000 000 копеек, необязательно |
| carriers | string[] | Необязательный список от 1 до 10 уникальных кодов |
У перевозчиков есть дополнительные ограничения на направления, размеры и вид груза. Успешная валидация Доставометра не гарантирует наличие тарифа.
cURLПример запроса
curl --fail-with-body https://api.dostavometr.ru/v1/rates \
-H "Authorization: Bearer $DOSTAVOMETR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": {
"country": "RU",
"city": "Чита",
"postal_code": "672000"
},
"to": {
"country": "RU",
"city": "Москва",
"postal_code": "101000"
},
"parcel": {
"weight_grams": 1000,
"length_cm": 30,
"width_cm": 20,
"height_cm": 15
}
}'PythonПример запроса
import json
import os
import urllib.request
payload = {
"from": {
"country": "RU",
"city": "Чита",
"postal_code": "672000"
},
"to": {
"country": "RU",
"city": "Москва",
"postal_code": "101000"
},
"parcel": {
"weight_grams": 1000,
"length_cm": 30,
"width_cm": 20,
"height_cm": 15
}
}
request = urllib.request.Request(
"https://api.dostavometr.ru/v1/rates",
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": "Bearer " + os.environ["DOSTAVOMETR_API_KEY"],
"Content-Type": "application/json",
},
)
with urllib.request.urlopen(request, timeout=30) as response:
print(json.load(response))PHPПример запроса
<?php
$key = getenv('DOSTAVOMETR_API_KEY');
if (!$key) { throw new RuntimeException('Set DOSTAVOMETR_API_KEY'); }
$ch = curl_init('https://api.dostavometr.ru/v1/rates');
$options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $key, 'Content-Type: application/json'],
];
$payload = json_decode(<<<'JSON'
{
"from": {
"country": "RU",
"city": "Чита",
"postal_code": "672000"
},
"to": {
"country": "RU",
"city": "Москва",
"postal_code": "101000"
},
"parcel": {
"weight_grams": 1000,
"length_cm": 30,
"width_cm": 20,
"height_cm": 15
}
}
JSON, true, 512, JSON_THROW_ON_ERROR);
$options[CURLOPT_POST] = true;
$options[CURLOPT_POSTFIELDS] = json_encode($payload, JSON_THROW_ON_ERROR);
curl_setopt_array($ch, $options);
$body = curl_exec($ch);
if ($body === false) { throw new RuntimeException(curl_error($ch)); }
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) { throw new RuntimeException($body); }
print_r(json_decode($body, true, 512, JSON_THROW_ON_ERROR));JavaScriptПример запроса
// Node.js 20+; запускайте на сервере, чтобы не раскрыть API-ключ.
const apiKey = process.env.DOSTAVOMETR_API_KEY;
if (!apiKey) throw new Error('Set DOSTAVOMETR_API_KEY');
const response = await fetch('https://api.dostavometr.ru/v1/rates', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"from": {
"country": "RU",
"city": "Чита",
"postal_code": "672000"
},
"to": {
"country": "RU",
"city": "Москва",
"postal_code": "101000"
},
"parcel": {
"weight_grams": 1000,
"length_cm": 30,
"width_cm": 20,
"height_cm": 15
}
}),
signal: AbortSignal.timeout(30000),
});
const result = await response.json();
if (!response.ok) throw new Error(JSON.stringify(result));
console.log(result);Нормализованный ответ
{
"request_id": "req_example",
"rates": [
{
"carrier": "russian_post",
"carrier_name": "Почта России",
"service_code": "parcel",
"service_name": "Посылка",
"delivery_type": "post_office",
"price_kopecks": 48700,
"currency": "RUB",
"days_min": 5,
"days_max": 7,
"price_type": "public"
}
],
"unavailable": [
{
"carrier": "dellin",
"reason": "not_configured"
}
],
"balance_remaining": 99
}Пример формата, без обещания указанных цены и сроков.
price_kopecks— целые копейки. ВалютаRUB.service_codeиservice_nameобозначают услугу конкретного перевозчика.days_min/days_max— ориентировочное число дней или null.price_type— источник ценовых условий; публичные тарифы помеченыpublic.balance_remaining— остаток на момент завершения запроса.
Типы доставки
| delivery_type | Значение |
|---|---|
| door | До двери |
| pickup_point | Пункт выдачи |
| terminal | Терминал |
| post_office | Почтовое отделение |
| unknown | Перевозчик не уточнил тип |
Списание и кэш
Один корректный расчёт стоит один запрос, независимо от числа перевозчиков. Кэшированный расчёт также списывает один запрос. Частичный результат — HTTP 200 и один запрос. Технический отказ всех перевозчиков — HTTP 503 и возврат зарезервированного запроса. Корректный пустой результат с причиной no_rates — HTTP 200 и списание одного запроса.
Повтор операции после сетевого сбоя выполняйте с тем же Idempotency-Key и тем же телом. Правила идемпотентности.
Стоимость и сроки являются расчётными. Фактическая стоимость может отличаться от расчётной в зависимости от условий перевозчика, характеристик груза и договора отправителя. Доставометр не является перевозчиком, не заключает договор перевозки, не принимает груз и не отвечает за фактический срок доставки.