For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
info@patternautomation.com
ДокументацияБаза знанийЖурнал измененийСправочник API
ДокументацияБаза знанийЖурнал измененийСправочник API
    • База знаний
  • С чего начать
    • Что такое Agent Inbox?
    • Возможности ящика
    • Первый ящик
    • Получение API-ключа
  • Сценарии для агентов
    • Входящие письма
    • Allowlist и blocklist
    • Тредовые переписки
    • Human-in-the-loop
    • Pods и мультитенантность
    • Метки и состояние
  • Домены и доставляемость
    • Свой домен
    • SPF, DKIM и DMARC
    • Письма в спаме
    • Прогрев домена
    • Конфликты MX
  • Решение проблем
    • Ошибка 403
    • Лимиты запросов
    • Дублирование отправок
    • Домен не верифицируется
    • Отказы доставки (bounce)
  • Настройка DNS
    • Cloudflare
    • GoDaddy
    • Route 53 (AWS)
    • Namecheap
info@patternautomation.com
LogoLogo
On this page
  • Создание ресурсов: clientId
  • Отправка писем: не через clientId на send
  • Метки как состояние
  • Черновики для критичных писем
  • Практика
Решение проблем

Как избежать повторной отправки?

Идемпотентность и учёт состояния.

Was this page helpful?
Edit this page
Previous

Почему домен не верифицируется?

Если верификация зависла или падает.

Next
Built with

Ретраи из-за сети или багов могут отправить одно письмо дважды. Ниже — как это предотвратить.

Создание ресурсов: clientId

Для create (ящики, pod, webhook, черновики) передайте clientId: если ресурс уже есть, API вернёт его, а не создаст дубликат.

TypeScript
1import { AgentinboxClient } from "agentinbox";
2
3const client = new AgentinboxClient({ apiKey: "am_..." });
4
5const inbox = await client.inboxes.create({
6 username: "support",
7 clientId: "support-inbox-v1",
8});
9
10const sameInbox = await client.inboxes.create({
11 username: "support",
12 clientId: "support-inbox-v1",
13});

Отправка писем: не через clientId на send

messages.send без встроенной идемпотентности ключа — логика в приложении.

Метки как состояние

TypeScript
1const threads = await client.inboxes.threads.list(inbox.inboxId, {
2 labels: ["unreplied"],
3});
4
5for (const thread of threads.threads) {
6 const detail = await client.threads.get(thread.threadId);
7 const lastMessage = detail.messages[detail.messages.length - 1];
8
9 await client.inboxes.messages.reply(inbox.inboxId, lastMessage.messageId, {
10 text: "Thanks for reaching out!",
11 });
12
13 await client.inboxes.messages.update(inbox.inboxId, lastMessage.messageId, {
14 addLabels: ["replied"],
15 removeLabels: ["unreplied"],
16 });
17}

Черновики для критичных писем

TypeScript
1const draft = await client.inboxes.drafts.create(inbox.inboxId, {
2 to: ["customer@example.com"],
3 subject: "Order confirmation",
4 text: "Your order has been confirmed.",
5 html: "<p>Your order has been confirmed.</p>",
6 clientId: "order-123-confirmation",
7});
8
9const sent = await client.inboxes.drafts.send(inbox.inboxId, draft.draftId);

После отправки черновик удаляется — повторный send не продублирует письмо.

Практика

  • clientId на всех create из бизнес-логики (order-${id}-...), не случайный UUID
  • Метки против двойной обработки одного сообщения
  • Черновики там, где дубликат недопустим

Подробнее: Идемпотентность.