Разработчикам · API v3

Обновление API: новые методы версионирования

Invoicx API v3 переосмысливает модель версий и генерации счетов: стабильные контракты, семантические теги и предсказуемые breaking-изменения. Ниже — что сломалось, как мигрировать и как писать новый код.

Релиз v3.0 · 12 марта 2025 · Поддержка v2 до 30 сентября 2025

Схема архитектуры Invoicx API v3 с потоком версионирования и endpoints генерации
v3.0
POST /v3/invoicesГенерация за 1 запрос, без ручных шагов
Что изменилось в архитектуре

Версия теперь часть контракта, а не заголовок

В v3 мы перешли от «одной живой версии» к явной семантической модели. Каждая мажорная версия — отдельный, неизменяемый контракт, который не меняется под ногами у клиента.

В v2 версия передавалась в заголовке Accept: application/vnd.invoicx.v2+json и могла «тихо» меняться. В v3 версия закреплена в URL-префиксе (/v3/...) и дополняется семантическим тегом X-Invoicx-Api-Version. Мажорные изменения больше не появляются без отдельного релиза и changelog — вы всегда знаете, какой контракт обслуживает ваш код.

Принципы v3

Как устроено версионирование

01

URL-префикс версии

Версия живёт в пути: /v3/invoices. Никаких скрытых переключателей — видно сразу, какой контракт вы вызываете.

02

Семантические теги

Ответы несут X-Invoicx-Api-Version: 3.2.1. Пэтчи добавляются без изменений контракта, мажор — только отдельным релизом.

03

Замороженные контракты

Поля, которые вы используете, не удаляются и не переименовываются внутри мажорной версии. Изменения — только в новой мажорке.

04

Явный sunset

Каждая версия получает дату отключения. Для v2 это 30.09.2025 — у вас есть время на спокойную миграцию.

05

Предсказуемые ошибки

Единый формат error с кодом, trace_id и ссылками на документацию. Никаких «500 без причины».

06

Идемпотентность

Все мутации принимают Idempotency-Key. Повторный вызов не создаст дубликат счёта — даже при ретраях.

Миграция с v2 на v3

Что именно поменять в коде

В подавляющем большинстве случаев миграция — это смена префикса и пара переименований полей. Ниже — полный список breaking-изменений.

Брейкинг 01

Префикс и заголовок

Замените /v2/ на /v3/ и уберите Accept: application/vnd.invoicx.v2+json. Версию теперь определяет путь.

Брейкинг 02

Переименование полей

invoice.totalinvoice.amount_total, customercounterparty. Старые имена отключены в v3.

Брейкинг 03

Статусы оплат

Перечисление payment_state расширено: добавлены partially_paid и disputed. Проверьте все сравнения.

Брейкинг 04

Формат дат

Все даты-время теперь строго ISO 8601 с часовым поясом (2025-03-12T14:30:00+03:00). Без таймзоны — ошибка 422.

Брейкинг 05

Постраничные ответы

Списки возвращают объект { items, next_cursor } вместо массива. Пагинация — по курсору, а не по page.

Брейкинг 06

Аутентификация

Ключ передаётся в Authorization: Bearer. Заголовок X-Invoicx-Key из v2 больше не принимается.

Новые endpoints для генерации

Генерация счетов — одним вызовом

v3 добавляет endpoints, которые в v2 требовали цепочку из трёх-четырёх запросов. Теперь генерация, проверка и отправка — предсказуемо и атомарно.

POST

/v3/invoices

Создаёт счёт по правилам выставления. Принимает rule_id или полный payload; возвращает объект со статусом draft.

POST

/v3/invoices/{id}:generate

Пересчитывает суммы и формирует финальные реквизиты из черновика. Идемпотентно — повторный вызов не изменит результат.

POST

/v3/invoices/{id}:issue

Выставляет счёт контрагенту и запускает слежение оплат. Статус переходит в issued, фиксируется issued_at.

GET

/v3/invoices/{id}/audit

Возвращает полный аудит-трейл: кто и когда менял суммы, условия и статусы. Каждое действие — с trace_id.

Кодовые примеры

Python и JavaScript на v3

Оба примера генерируют и выставляют счёт по правилу, передавая Idempotency-Key для безопасных ретраев.

Python · requests

Генерация и выставление

import requests

API = "https://api.invoicx.io/v3"
H = {
    "Authorization": "Bearer ix_live_9f2a…",
    "Idempotency-Key": "inv-gen-2025-03-12-001",
}

# Генерация по правилу выставления
gen = requests.post(
    f"{API}/invoices",
    headers=H,
    json={"rule_id": "rule_recurring_04", "due_in_days": 14},
)
gen.raise_for_status()
invoice_id = gen.json()["id"]

# Финализация сумм
requests.post(f"{API}/invoices/{invoice_id}:generate", headers=H)

# Выставление контрагенту
issued = requests.post(f"{API}/invoices/{invoice_id}:issue", headers=H)
print(issued.json()["payment_state"])  # "issued"
        
JavaScript · fetch

Генерация и выставление

const API = "https://api.invoicx.io/v3";
const H = {
  "Authorization": "Bearer ix_live_9f2a…",
  "Idempotency-Key": "inv-gen-2025-03-12-001",
};

async function issueFromRule(ruleId) {
  const gen = await fetch(`${API}/invoices`, {
    method: "POST",
    headers: H,
    body: JSON.stringify({ rule_id: ruleId, due_in_days: 14 }),
  });
  if (!gen.ok) throw new Error("gen " + gen.status);
  const { id } = await gen.json();

  await fetch(`${API}/invoices/${id}:generate`, { method: "POST", headers: H });
  const issued = await fetch(`${API}/invoices/${id}:issue`, {
    method: "POST",
    headers: H,
  });
  const data = await issued.json();
  console.log(data.payment_state); // "issued"
}

issueFromRule("rule_recurring_04");
        

Проверьте свой код на v3

Подключите тестовый ключ и прогоните миграцию в песочнице — до того, как v2 уйдёт в sunset 30 сентября.