Почтовые тарифы через единый API
Доставометр обращается к официальному тарифному API Почты России tariff.pochta.ru. В первой версии рассчитывается услуга «Посылка»: обычная или с объявленной ценностью. В ответе — стоимость и ориентировочный срок, если его сообщает перевозчик.
Какие данные нужны
- Индексы отправления и получения: шесть цифр.
- Названия городов для единого формата запроса.
- Вес в граммах и три габарита в сантиметрах.
- При необходимости — объявленная стоимость в копейках.
Что возвращает сервис
Тарифы в целых копейках, код и название почтовой услуги, тип доставки post_office и доступный диапазон сроков. Публичный тариф помечается price_type: public.
Ограничения
Расчёт первой версии предназначен для отправлений по России. Неверный или отсутствующий индекс может сделать почтовый расчёт недоступным, даже если другие службы вернули тариф. Итоговые условия зависят от почтового продукта, фактического веса, упаковки и дополнительных услуг.
Официальная документация тарифного API Почты России.
Пример запроса
Укажите carriers: ["russian_post"], чтобы запросить только эту службу. Ключ храните на сервере.
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
},
"carriers": [
"russian_post"
]
}'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
},
"carriers": [
"russian_post"
]
}
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
},
"carriers": [
"russian_post"
]
}
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
},
"carriers": [
"russian_post"
]
}),
signal: AbortSignal.timeout(30000),
});
const result = await response.json();
if (!response.ok) throw new Error(JSON.stringify(result));
console.log(result);Единый результат
В каждом тарифе есть price_kopecks, days_min, days_max, delivery_type и price_type. Если перевозчик не ответил, причина находится в unavailable.
Цена ориентировочная: итоговую стоимость и возможность отправки подтверждает перевозчик.