Версия 1 · чтение переписки и черновики ответов для CRM и других проектов
Базовый адрес: https://wa-me.im/api/v1. Все запросы и ответы — JSON в UTF-8, время — ISO 8601 (UTC) и миллисекунды Unix.
Каждый запрос с заголовком:
Authorization: Bearer <ключ>
Ключи выпускает владелец пространства: ⚙ Настройки → Ключи API → Создать. Ключ показывается один раз — сохраните его
в менеджере паролей и передавайте в проект через переменные окружения, не записывайте в код. Ключ видит только номера своего
пространства; его название попадает в поле source черновика. Отозвать ключ можно там же. Лимит — 120 запросов в минуту на ключ.
business (WhatsApp Business), personal (личный) и добавленные позже. Список — GET /accounts.+598 99 123 456, 59899123456. Пробелы, плюсы и скобки игнорируются. В пути URL — только цифры.…@g.us, есть в ответе GET /chats), в пути — URL-кодированным.curl -H "Authorization: Bearer $WA_API_KEY" https://wa-me.im/api/v1/accounts
{ "accounts": [
{ "account": "business", "title": "Business", "connected": true, "phone": "+59897323353", "name": "Fluenta" },
{ "account": "personal", "title": "Личный", "connected": true, "phone": "+59892804681", "name": null }
] }
| Параметр | Описание |
|---|---|
account | Аккаунт (необязательно; без него — все) |
q | Поиск по имени или цифрам номера |
limit | Сколько вернуть, по умолчанию 50, максимум 500. Сортировка — по последнему сообщению, новые сверху |
curl -H "Authorization: Bearer $WA_API_KEY" "https://wa-me.im/api/v1/chats?account=business&q=belu"
{ "chats": [ {
"account": "business", "chat": "5493513049992@s.whatsapp.net", "phone": "+5493513049992", "name": "Belu",
"last_message_at": "2025-10-13T15:56:52.000Z", "last_message": "[голосовое сообщение]", "last_from_me": false,
"messages": 10, "unread": 2, "pending_drafts": 0
} ] }
| Параметр | Описание |
|---|---|
limit | По умолчанию 50, максимум 500 |
before | Только сообщения раньше этого момента (мс Unix) — листать историю назад |
after | Только новее этого момента (мс Unix) — забирать новые с прошлого запроса |
Сообщения всегда идут от старых к новым. Без before/after — последние limit штук.
curl -H "Authorization: Bearer $WA_API_KEY" \
"https://wa-me.im/api/v1/chats/business/5493513049992/messages?limit=20"
{ "account": "business", "chat": "5493513049992@s.whatsapp.net", "phone": "+5493513049992",
"messages": [ {
"id": "3AC8667914EFE184D44F", "direction": "in", "at": "2025-10-13T15:56:52.000Z", "ts": 1760371012000,
"sender": { "phone": "+5493513049992", "name": "Belu" },
"type": "voice", "text": "Buen día, feliz comienzo de semana…",
"translation_ru": "Доброе утро, хорошего начала недели…",
"media_url": "/api/v1/media/business/3AC8667914EFE184D44F", "status": null
}, {
"id": "3EB0…", "direction": "out", "at": "…", "ts": 1760372000000, "sender": null,
"type": "text", "text": "¡Hola, Belu! Gracias por escribir.", "translation_ru": "Привет, Белу! Спасибо, что написала.",
"media_url": null, "status": "read"
} ] }
| Поле | Значение |
|---|---|
direction | in — от собеседника, out — наше |
type | text, image, video, voice, document, sticker |
text | Текст или подпись к вложению; у голосовых — распознанная речь, если её уже распознали в интерфейсе |
translation_ru | Входящие: перевод на русский (null — ещё не переводили, "" — перевод не нужен). Наши: русский исходник ответа, если писали через перевод |
status | Только у наших: pending, sent ✓, delivered ✓✓, read (синие ✓✓), played (голосовое прослушано), error; null — неизвестно |
Отдаёт сам файл (картинку, PDF, голосовое ogg) с правильным Content-Type. Адрес — из поля media_url. Старые файлы, которых уже нет на серверах WhatsApp, отвечают 404 media_unavailable.
| Поле | Описание |
|---|---|
account | Аккаунт, по умолчанию business |
phone или chat | Номер собеседника или идентификатор чата. Чат может быть новым — он появится в списке с пометкой «черновик» |
ru | Текст по-русски. Если text не передан, переведём на язык собеседника с учётом переписки (испанский — уругвайский, тон и обращение как в переписке) |
text | Готовый текст на языке собеседника — будет отправлен как есть. Можно передать вместе с ru, тогда перевода не будет |
lang | Язык перевода (es, en, pt…), по умолчанию — язык собеседника |
translate | false — не переводить ru сейчас (переведёт человек кнопкой в интерфейсе) |
attachment | Картинка или файл: { "url": "https://…/invoice.pdf" } — скачаем сами (http/https, до 64 МБ, 30 с),
или { "data": "<base64>", "name": "счёт.pdf", "mime": "application/pdf" }. name и mime необязательны — определим по ссылке и расширению.
JPG/PNG/WebP уйдут фото, MP4/MOV — видео, остальное — документом; текст черновика станет подписью |
note | Пометка для человека, видна над полем ответа: «Счёт № 512», «ответ на запрос цены» |
external_id | Ваш идентификатор (например, id задачи в CRM). Повторный запрос с тем же external_id, пока черновик не обработан, не создаёт дубль — вернётся существующий с "duplicate": true |
source | Откуда черновик, по умолчанию — имя ключа (crm) |
Нужен хотя бы один из ru / text / attachment. Перевод занимает 1–3 секунды.
curl -X POST https://wa-me.im/api/v1/drafts \
-H "Authorization: Bearer $WA_API_KEY" -H "Content-Type: application/json" \
-d '{
"account": "business",
"phone": "+54 9 351 304-9992",
"ru": "Добрый день! Счёт на оплату отправили на почту. Если будут вопросы — пишите.",
"note": "Счёт № 512",
"external_id": "deal-512-invoice"
}'
HTTP/1.1 201 Created
{ "draft": {
"id": "drf_3f9c2a7b1e4d4c0a9b12", "account": "business", "chat": "5493513049992@s.whatsapp.net", "phone": "+5493513049992",
"ru": "Добрый день! Счёт на оплату отправили на почту. Если будут вопросы — пишите.",
"text": "¡Buen día! Te mandamos la factura por mail. Cualquier duda, escribinos.",
"lang": "es", "source": "crm", "note": "Счёт № 512", "external_id": "deal-512-invoice",
"status": "pending", "message_id": null,
"created_at": "2026-10-24T13:30:00.000Z", "updated_at": "2026-10-24T13:30:00.000Z"
} }
С вложением:
curl -X POST https://wa-me.im/api/v1/drafts \
-H "Authorization: Bearer $WA_API_KEY" -H "Content-Type: application/json" \
-d '{
"phone": "+59899123456",
"ru": "Отправляю счёт на оплату за ноябрь.",
"attachment": { "url": "https://crm.example.com/files/invoice-512.pdf", "name": "Factura-512.pdf" },
"external_id": "invoice-512"
}'
В ответе у черновика появится "attachment": { "name", "mime", "size", "url": "/api/v1/drafts/drf_…/attachment" }.
В интерфейсе вложение прикрепится к полю ответа вместе с текстом — человек увидит превью и отправит.
Файл вложения черновика.
| Параметр | Описание |
|---|---|
account, phone / chat | Фильтр по аккаунту и собеседнику |
status | pending — ждёт человека, sent — отправлен (в message_id — id сообщения), discarded — отклонён |
limit | По умолчанию 100, максимум 500; новые сверху |
curl -H "Authorization: Bearer $WA_API_KEY" "https://wa-me.im/api/v1/drafts?status=sent&limit=20"
Текущее состояние — удобно проверять, отправил ли человек ответ. После отправки status = "sent", а text остаётся в том виде, в каком его предложили (человек мог поправить — фактический текст ищите по message_id в сообщениях).
Отозвать черновик, пока он не отправлен (status → "discarded"). Для отправленного — 409 draft_not_pending.
{ "error": { "code": "account_not_found", "message": "Нет аккаунта «biz». Список: GET /api/v1/accounts" } }
| HTTP | code | Когда |
|---|---|---|
| 400 | bad_request | Нет номера, нет текста, номер не похож на номер |
| 401 | unauthorized | Нет ключа или ключ неверный |
| 404 | account_not_found, draft_not_found, media_unavailable, not_found | Нет такого аккаунта, черновика, файла или метода |
| 402 | quota_exceeded | Исчерпан месячный лимит перевода бесплатного тарифа (черновик с ru без text) |
| 429 | rate_limited | Больше 120 запросов в минуту |
| 409 | draft_not_pending | Черновик уже отправлен или отклонён |
| 413 | attachment_too_large | Вложение больше 64 МБ |
| 422 | attachment_fetch_failed | Не удалось скачать вложение по ссылке (ошибка сети, таймаут, не 2xx) |
| 500 | internal | Например, недоступен сервис перевода — повторите позже или передайте готовый text |
const WA = 'https://wa-me.im/api/v1'
const headers = { Authorization: `Bearer ${process.env.WA_API_KEY}`, 'Content-Type': 'application/json' }
// 1. Последние сообщения клиента — показать в карточке сделки
const { messages } = await fetch(`${WA}/chats/business/5493513049992/messages?limit=30`, { headers }).then(r => r.json())
// 2. Черновик ответа по-русски — менеджер проверит и отправит в WhatsApp Inbox
const { draft } = await fetch(`${WA}/drafts`, {
method: 'POST', headers,
body: JSON.stringify({ phone: '+5493513049992', ru: 'Здравствуйте! Договор готов, отправить на почту?', external_id: 'deal-77' }),
}).then(r => r.json())
// 3. Позже — узнать, ушёл ли ответ
const state = await fetch(`${WA}/drafts/${draft.id}`, { headers }).then(r => r.json())
console.log(state.draft.status) // pending | sent | discarded
Каждый запрос к API пишется в data/events.log: ключ, метод, путь, код ответа и время (тела запросов и ключи — нет).
Ошибки со стеком — в data/errors.log. Если интеграция получает 5xx — смотрите там по времени запроса.