Справочник HTTP API
Полная спецификация REST API без использования SDK. Для интерактивной проверки см. API Playground.
Эндпоинт
https://meters-api-prod.nyc-1.optimatica.pro/api/meters/analyzeВ SDK этот URL зашит на этапе сборки (переменная OPTIMATICA_API_URL).
Аутентификация
Каждый запрос к /api/* должен содержать заголовок:
http
Authorization: Bearer ВАШ_JWT| Параметр | Описание |
|---|---|
| Формат ключа | JWT (header.payload.signature), без префикса |
| Срок действия | До явного отзыва в личном кабинете |
| Передача | Только заголовок Authorization, не query-параметр |
Ошибки авторизации
| HTTP | Тело | Причина |
|---|---|---|
| 401 | { "error": "Unauthorized" } | Ключ отсутствует, неверный или отозван |
| 403 | { "error": "Client blocked" } | Аккаунт заблокирован |
| 402 | { "error": "Payment required" } | Исчерпана квота запросов |
Эндпоинты
| Метод | Путь | Описание |
|---|---|---|
POST | /api/meters/analyze | Распознавание счётчика по фото |
POST /api/meters/analyze
Анализирует фотографию счётчика и возвращает тип, серийный номер и показания.
Запрос
http
POST /api/meters/analyze
Authorization: Bearer ВАШ_JWT
Content-Type: multipart/form-data| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
image | file | да | JPEG или PNG, фото счётчика (до 20 MB) |
WARNING
Имя поля формы должно быть image. Другие имена вернут 400.
cURL
bash
curl -X POST https://meters-api-prod.nyc-1.optimatica.pro/api/meters/analyze \
-H "Authorization: Bearer ВАШ_JWT" \
-F "image=@/path/to/meter.jpg"fetch (браузер / Node 18+)
js
const form = new FormData()
form.append('image', file)
const res = await fetch('https://meters-api-prod.nyc-1.optimatica.pro/api/meters/analyze', {
method: 'POST',
headers: { Authorization: 'Bearer ВАШ_JWT' },
body: form,
})
const data = await res.json()Python (requests)
python
import requests
with open('meter.jpg', 'rb') as f:
res = requests.post(
'https://meters-api-prod.nyc-1.optimatica.pro/api/meters/analyze',
headers={'Authorization': 'Bearer ВАШ_JWT'},
files={'image': f},
)
data = res.json()Ответы
Успешное распознавание — HTTP 200
json
{
"success": true,
"meter": {
"type": "water_cold",
"serialNumber": "12345678",
"currentReading": 123.456,
"tariffCount": null,
"waterTypeUnknown": false
}
}| Поле | Тип | Описание |
|---|---|---|
success | boolean | Всегда true |
meter.type | string | Тип счётчика — см. типы |
meter.serialNumber | string | Заводской номер с шильдика |
meter.currentReading | number | null | Показания; null если не читаются |
meter.tariffCount | number | null | Число тарифных зон (электросчётчики) |
meter.waterTypeUnknown | boolean? | true если тип воды не определился |
Не удалось распознать — HTTP 200
API возвращает 200, но success: false — это не HTTP-ошибка:
json
{
"success": false,
"error": "Could not detect meter in the photo"
}| Поле | Тип | Описание |
|---|---|---|
success | boolean | Всегда false |
error | string | Человекочитаемая причина |
HTTP-ошибки
| HTTP | Пример тела | Когда |
|---|---|---|
| 400 | { "error": "No file uploaded" } | Нет поля image или неверный формат |
| 401 | { "error": "Unauthorized" } | Проблема с API-ключом |
| 402 | { "error": "Payment required" } | Квота исчерпана |
| 403 | { "error": "Client blocked" } | Клиент заблокирован |
| 500 | { "error": "..." } | Внутренняя ошибка сервера |
Типы счётчиков (meter.type)
| Значение | Описание |
|---|---|
water_cold | Холодная вода |
water_hot | Горячая вода |
electricity | Электричество |
gas | Газ |
heat | Теплоснабжение |
Ограничения
| Параметр | Значение |
|---|---|
| Форматы изображения | JPEG, PNG |
| Максимальный размер | 20 MB |
| Content-Type запроса | multipart/form-data |
| Поле файла | image |
SDK
HTTP-вызовы можно не писать вручную — используйте пакет optimatica-meters:
ts
import { analyzeMeterPhoto, ZhkhApiError } from 'optimatica-meters'
try {
const result = await analyzeMeterPhoto(file, { apiKey: 'eyJhbGci...' })
if (result.success) {
console.log(result.meter.serialNumber)
}
} catch (err) {
if (err instanceof ZhkhApiError) {
console.log(err.status, err.message)
}
}UI-компоненты с камерой и drag-and-drop: Vue Playground, React Playground.