Referência/Message Batches/createMessageBatch
Message Batches

Cria um lote persistente

Persiste a definição, os destinatários normalizados, as instâncias permitidas e a agenda opcional. Com autoStart=true, o estado inicial é QUEUED, SCHEDULED ou WAITING_FOR_WINDOW conforme a janela.

Pro
POSThttp://localhost:8084/message/batches

Autenticação

UserBearerobrigatório

JWT HS256 de usuario. Deve conter userId em formato UUID e exp; a expiracao sempre e validada.

Header
Authorization
Exemplo
Bearer <INSTANCE_TOKEN>

Request body

obrigatório
bodyobject
Exemplo: {"name":"Aviso de manutenção","instances":["codechat-01","codechat-02"],"recipients":["5531999999999","5531888888888"],"message":{"type":"interactive","payload":{"title":"Confirmação","description":"Deseja continuar?","footerText":"CodeChat","buttons":[{"displayText":"Repo","url":"https://github.com/code-chat-br/whatsapp-api-go"},{"displayText":"Código de barras","copyCode":"32546413216543165489869589416558645341864321365468435469465"},{"displayText":"Sim","id":"1"},{"displayText":"Não","id":"0"},{"displayText":"Talvez","id":"-1"}]}},"options":{"replicable":true,"presence":"composing","delay":{"minMs":3000,"maxMs":12000}},"autoStart":false,"autoResume":true,"schedule":{"windowStartAt":"2026-07-16T00:00:00-03:00","windowEndAt":"2026-07-16T03:00:00-03:00","recurrence":"DAILY","timezone":"America/Sao_Paulo"},"externalAttributes":{"origin":"admin-panel"}}
namestringobrigatóriominLength: 1 · maxLength: 255
instancesarrayobrigatório

Nomes de instâncias existentes e com autenticação disponível.

items[]stringminLength: 1 · maxLength: 255
recipientsarrayobrigatório

Somente contatos individuais. O limite é definido por MESSAGE_BATCH_MAX_RECIPIENTS e duplicados normalizados são ignorados.

items[]stringminLength: 1
messageobjectobrigatório

Mensagem persistida do lote. O payload é direto: não envie number/chat/recipient/options nem wrappers como textMessage, mediaMessage, audioMessage, contactMessage, locationMessage ou buttonMessage. Tipos aceitos: text, link, media, audio, contact, location e interactive; ptt, whatsapp-audio e whatsapp_audio são aliases de audio.

typeenum<text | link | media | audio | ptt | whatsapp-audio | whatsapp_audio | contact | location | interactive>obrigatório
payloadoneOfobrigatório

Objeto ou array persistente conforme message.type: text={text}; link={link,thumbnailUrl,title,description}; media={mediatype,media|mediaUploadId,fileName,caption}; audio={audio} ou {mediaUploadId,ptt:true}; contact=[{fullName,phoneNumber,wuid,organization,vcard}]; location={latitude,longitude,name,address,url}; interactive segue MessageBatchInteractivePayload.

opção 1object
opção 2array
items[]object
optionsobject
replicableboolean

Preservado no contrato; não adiciona semântica própria no worker.

presenceenum<composing | recording | paused>
delayobject

Campos ausentes assumem zero. maxMs precisa ser maior ou igual a minMs e respeitar MESSAGE_BATCH_MAX_DELAY_MS.

minMsintegerformat: int64 · padrão: 0 · mín: 0
maxMsintegerformat: int64 · padrão: 0 · mín: 0
quotedMessageIdintegerformat: int64
quotedMessageobject
externalAttributesobject
mentionAllboolean

Somente false é aceito; true é rejeitado porque lotes não aceitam grupos.

autoStartbooleanpadrão: false
autoResumebooleanpadrão: true

Recupera automaticamente interrupções operacionais; nunca ignora PAUSED.

scheduleobject
windowStartAtstringobrigatórioformat: date-time
windowEndAtstringobrigatórioformat: date-time
recurrenceenum<NONE | DAILY>obrigatório
timezonestring

Timezone IANA. Quando omitido, usa MESSAGE_BATCH_TIMEZONE.

externalAttributesobject

Objeto JSON com até 64 KiB.

Exemplo JSONgerado do schema
{
"name": "Aviso de manutenção",
"instances": [
"codechat-01",
"codechat-02"
],
"recipients": [
"5531999999999",
"5531888888888"
],
"message": {
"type": "interactive",
"payload": {
"title": "Confirmação",
"description": "Deseja continuar?",
"footerText": "CodeChat",
"buttons": [
{
"displayText": "Repo",
"url": "https://github.com/code-chat-br/whatsapp-api-go"
},
{
"displayText": "Código de barras",
"copyCode": "32546413216543165489869589416558645341864321365468435469465"
},
{
"displayText": "Sim",
"id": "1"
},
{
"displayText": "Não",
"id": "0"
},
{
"displayText": "Talvez",
"id": "-1"
}
]
}
},
"options": {
"replicable": true,
"presence": "composing",
"delay": {
"minMs": 3000,
"maxMs": 12000
}
},
"autoStart": false,
"autoResume": true,
"schedule": {
"windowStartAt": "2026-07-16T00:00:00-03:00",
"windowEndAt": "2026-07-16T03:00:00-03:00",
"recurrence": "DAILY",
"timezone": "America/Sao_Paulo"
},
"externalAttributes": {
"origin": "admin-panel"
}
}

Respostas

application/json
201

Lote criado em DRAFT, SCHEDULED, QUEUED ou WAITING_FOR_WINDOW

response 201object
idstringobrigatórioformat: uuid
ownerUserIdstringobrigatórioformat: uuid
namestringobrigatório
statusenum<DRAFT | SCHEDULED | QUEUED | PROCESSING | PAUSE_REQUESTED | PAUSED | WAITING_FOR_INSTANCE | WAITING_FOR_WINDOW | STOP_REQUESTED | STOPPED | INTERRUPTED | COMPLETED | COMPLETED_WITH_ERRORS | FAILED>obrigatório
messageobject

Mensagem persistida do lote. O payload é direto: não envie number/chat/recipient/options nem wrappers como textMessage, mediaMessage, audioMessage, contactMessage, locationMessage ou buttonMessage. Tipos aceitos: text, link, media, audio, contact, location e interactive; ptt, whatsapp-audio e whatsapp_audio são aliases de audio.

typeenum<text | link | media | audio | ptt | whatsapp-audio | whatsapp_audio | contact | location | interactive>obrigatório
payloadoneOfobrigatório

Objeto ou array persistente conforme message.type: text={text}; link={link,thumbnailUrl,title,description}; media={mediatype,media|mediaUploadId,fileName,caption}; audio={audio} ou {mediaUploadId,ptt:true}; contact=[{fullName,phoneNumber,wuid,organization,vcard}]; location={latitude,longitude,name,address,url}; interactive segue MessageBatchInteractivePayload.

opção 1object
opção 2array
items[]object
optionsobject
replicableboolean

Preservado no contrato; não adiciona semântica própria no worker.

presenceenum<composing | recording | paused>
delayobject
minMsintegerobrigatórioformat: int64 · padrão: 0 · mín: 0
maxMsintegerobrigatórioformat: int64 · padrão: 0 · mín: 0
quotedMessageIdintegerformat: int64
quotedMessageobject
externalAttributesobject
mentionAllboolean

Somente false é aceito; true é rejeitado porque lotes não aceitam grupos.

externalAttributesobject
instancesarrayobrigatório
items[]object
idintegerobrigatório
namestringobrigatório
connectionStatusstring
selectedCountintegerformat: int64
successCountintegerformat: int64
failedCountintegerformat: int64
countsobjectobrigatório
receivedintegerformat: int64 · mín: 0
totalintegerobrigatórioformat: int64 · mín: 0
duplicatesIgnoredintegerformat: int64 · mín: 0
processedintegerobrigatórioformat: int64 · mín: 0
pendingintegerobrigatórioformat: int64 · mín: 0
sendingintegerobrigatórioformat: int64 · mín: 0
successintegerobrigatórioformat: int64 · mín: 0
failedintegerobrigatórioformat: int64 · mín: 0
skippedintegerobrigatórioformat: int64 · mín: 0
unknownintegerobrigatórioformat: int64 · mín: 0
progressintegerobrigatóriomín: 0 · máx: 100

floor(processed * 100 / total).

autoResumebooleanobrigatório
scheduleoneOfobrigatório
opção 1object

Janela absoluta inicial. DAILY preserva os horários locais e aceita janelas que atravessam a meia-noite.

windowStartAtstringobrigatórioformat: date-time
windowEndAtstringobrigatórioformat: date-time
recurrenceenum<NONE | DAILY>obrigatório
timezonestringobrigatório

Timezone IANA usado no cálculo da recorrência.

opção 2null
nextRunAtstring | nullobrigatórioformat: date-time
lastInterruptedAtstring | nullobrigatórioformat: date-time
interruptionReasonenum<GRACEFUL_SHUTDOWN | LEASE_EXPIRED | PROCESS_CRASH | SEND_TIMEOUT_DURING_SHUTDOWN | null>obrigatório
lastRecoveredAtstring | nullobrigatórioformat: date-time
currentItemobject
idstringobrigatórioformat: uuid
positionintegerobrigatóriomín: 0
recipientstringobrigatório
instanceNamestring | nullobrigatório
lastErrorstring
createdAtstringobrigatórioformat: date-time
startedAtstringformat: date-time
pausedAtstringformat: date-time
stoppedAtstringformat: date-time
completedAtstringformat: date-time
interruptedAtstringformat: date-time
updatedAtstringobrigatórioformat: date-time
Exemplo 201
{
"id": "01900000-0000-7000-8000-000000000001",
"ownerUserId": "11111111-1111-4111-8111-111111111111",
"name": "Aviso de manutenção",
"status": "DRAFT",
"autoResume": true,
"schedule": null,
"nextRunAt": null,
"lastInterruptedAt": null,
"interruptionReason": null,
"lastRecoveredAt": null,
"instances": [
{
"id": 1,
"name": "codechat-01",
"connectionStatus": "offline"
},
{
"id": 2,
"name": "codechat-02",
"connectionStatus": "online"
}
],
"counts": {
"received": 2,
"total": 2,
"processed": 0,
"pending": 2,
"sending": 0,
"success": 0,
"failed": 0,
"skipped": 0,
"unknown": 0
},
"progress": 0,
"externalAttributes": {
"origin": "admin-panel"
},
"createdAt": "2026-07-13T15:00:00Z",
"updatedAt": "2026-07-13T15:00:00Z"
}