Идемпотентные запросы

Как использовать ключи идемпотентности для надёжных интеграций с API.

Что такое идемпотентность?

В контексте API идемпотентность значит: повтор одного и того же запроса даёт тот же эффект, что и один вызов. Если идемпотентный POST на создание ресурса отправить пять раз, ресурс создаётся только при первом успешном ответе; остальные четыре не создают новых сущностей, а возвращают результат первого.

Это важно для устойчивых систем: сетевые сбои, таймауты и повторы на клиенте неизбежны. Без идемпотентности можно получить дубликаты — несколько одинаковых inbox или вебхуков.

Как Agent Inbox обеспечивает идемпотентность

Для всех операций create поддерживается необязательный параметр client_id.

Если в запросе на create передан client_id, платформа проверяет, был ли уже успешно выполнен запрос с таким же client_id.

  • В первый раз запрос обрабатывается как обычно: ресурс создаётся, а связь client_id → идентификатор ресурса сохраняется.
  • Если такой client_id уже был — запрос не выполняется повторно; сразу возвращается 200 OK с данными первого успешного ответа.

Так можно безопасно повторять запросы без риска дубликатов.

1# Первый запуск создаёт новый inbox.
2inbox = client.inboxes.create(
3 username="idempotent-test",
4 client_id="user-123-inbox-primary"
5)
6print(f"Created inbox: {inbox.id}")
7
8# Тот же код снова НЕ создаст второй inbox — вернётся тот же объект.
9inbox_again = client.inboxes.create(
10 username="idempotent-test",
11 client_id="user-123-inbox-primary"
12)
13print(f"Retrieved same inbox: {inbox_again.id}")
14# inbox.id совпадёт в обоих случаях.

Рекомендации по client_id

client_id должен быть уникальным для создаваемой сущности и детерминированным для одной и той же логической сущности у вас.

  • Детерминированность: одна и та же сущность у вас всегда даёт один и тот же client_id, например inbox-for-user-{{USER_ID}} для основного ящика пользователя.
  • Уникальность: не переиспользуйте client_id для разных типов ресурсов. Тот же ключ, что для inbox, не подходит для вебхука.

Надёжный приём: сгенерировать на клиенте UUID (например v4) для создаваемого ресурса, сохранить его у себя в БД и передать как client_id в API — тогда при любых повторах ключ стабилен.