Help Center Integração de API Meta e Instagram

Integração de API Meta e Instagram

Referência para construção de um aplicativo Instagram na Plataforma SMSBAT ChatHub: autenticação, Conversas do Instagram Direct, comentários em postagens e Momentos, respostas de histórias, webhooks e enquetes.

Fontes

Esta página mescla a especificação interna da API Meta Comments com a OpenAPI ativa definições em https://chatapi.smsbat.com/swagger/v1/swagger.json e https://restapi.smsbat.com/swagger/v1/swagger.json. Onde os dois discordam, o a diferença é destacada in-line e listada em Perguntas abertas.


1. URLs básicos

FinalidadeURL
API de bate-papo + MetaAPIhttps://chatapi.smsbat.com
UI Swagger / OpenAPIhttps://chatapi.smsbat.com/index.html · …/swagger/v1/swagger.json
API REST (organizações, URLs de retorno de chamada)https://restapi.smsbat.com
Arrogância da API RESThttps://restapi.smsbat.com/swagger/v1/swagger.json
Painel web do operadorhttps://chat.smsbat.com

2. Autenticação

O esquema de autenticação depende do grupo de endpoints. Misturá-los é a causa mais comum de 401.

GrupoCabeçalho
chatapi.smsbat.com/api/meta/* (postagens, comentários)X-Authorization-Key: <organization token>
chatapi.smsbat.com/api/chat/*, /api/company/*, /api/operator/*Authorization: Bearer <JWT>
restapi.smsbat.com/*X-Authorization-Key · Authorization: Bearer · Autenticação Básica

O token de organização para X-Authorization-Key é emitido no painel em Perfil. Os JWTs da empresa e da operadora vêm de /api/company/get-token e /api/operator/get-token.

Discrepância

O documento chatapi OpenAPI declara um único esquema de segurança — Bearer — e o aplica globalmente. X-Authorization-Key não é declarado lá, embora o Meta interno A especificação da API de comentários nomeia-o como /api/meta/*. Provavelmente é tratado por middleware que não é refletido no Swagger. Confirme empiricamente antes de enviar.

2.1 Token da empresa

POST https://chatapi.smsbat.com/api/company/get-token
Content-Type: application/json

{ "login": "company_login", "password": "company_password" }

200 OK retorna uma string de token simples.

2.2 Organizações

GET https://chatapi.smsbat.com/api/company/organization
Authorization: Bearer <company_token>
[ { "id": 24, "name": "My Instagram Store" } ]

2.3 Operadores em uma organização

GET https://chatapi.smsbat.com/api/operator?organizationId=24
Authorization: Bearer <company_token>
[
  {
    "id": 21,
    "name": "Jane Doe",
    "status": 0,
    "organization": { "id": 24, "name": "My Instagram Store" }
  }
]

Status do operador: 0 Ativo, 1 Inativo, 2 Excluído.

2.4 Adicionar/sincronizar operadores

POST https://chatapi.smsbat.com/api/operator/synchronize
Authorization: Bearer <company_token>
Content-Type: application/json

[ { "organizationId": 24, "name": "John Operator" } ]

200 OK → [ { "id": 21, "status": 0, "name": "John Operator" } ]

2.5 Operador JWT

POST https://chatapi.smsbat.com/api/operator/get-token
Authorization: Bearer <company_token>
Content-Type: application/json

{ "id": 21, "expiresAt": "2026-12-31T23:59:59.000Z" }

200 OK retorna o JWT como uma string.

2.6 Validar um token de operador

POST https://chatapi.smsbat.com/api/operator/validate-token
Authorization: Bearer <company_token>
Content-Type: application/json

"eyJhbGciOi..."
{
  "isValid": true,
  "operatorId": 21,
  "clientId": 0,
  "expiresAt": "2026-12-31T23:59:59.000Z",
  "error": null
}

Quando inválido: { "isValid": false, "error": "Invalid token" }.

2.7 Incorporar o painel de bate-papo do operador

<script type="module" id="operator-chat-panel-script"
  src="https://widget.smsbat.com/operator-chat-panel/widget-script.js"
  token="YOUR_OPERATOR_JWT_TOKEN"></script>

Um sistema externo (CRM, ERP, site) pode abrir uma conversa específica em https://chat.smsbat.com/. O operador é autorizado por um JWT passado como parâmetro de consulta.

https://chat.smsbat.com/?chat_raw_id=<chat_id>&token=<jwt>
https://chat.smsbat.com/?phone=<phone>&token=<jwt>
https://chat.smsbat.com/?from=<bm_id>&phone=<phone>&token=<jwt>
https://chat.smsbat.com/?source=7&from=<bm_id>&phone=<phone>&token=<jwt>
ParâmetroDescrição
chat_raw_idID do bate-papo
phoneNúmero de telefone em formato internacional
fromIdentificador de marca/conta comercial (bm_id)
sourceFonte de bate-papo — 7 para Instagram, consulte §8.1
tokenOperador JWT válido e não expirado com acesso a chats

Um JWT inválido leva o visitante à tela de login do painel do operador.


4. Conversas diretas do Instagram

4.1 Listar bate-papos

GET https://chatapi.smsbat.com/api/chat/chats?source=7&page=1&per_page=20
Authorization: Bearer <token>

Note

A paginação aqui é per_page (snake_case). Sob /api/meta/* e a votação ponto final é perPage (camelCase). Isso não é um erro de digitação — a API usa ambos.

Parâmetros de consulta, todos opcionais:

ParâmetroTipoDescrição
sourceChatSource7 restringe resultados ao Instagram
entityIdintID da conta comercial. Aplicado apenas em conjunto com source
instagram_user_idintID de usuário do Instagram no ChatHub
facebook_user_idintID de usuário do Facebook no ChatHub
page / per_pageintPaginação, padrões 1 / 20
statusChatStatus[]Status do bate-papo, repetível
searchstringPesquisa de texto livre (nome, telefone, …)
organizationIdintID da organização
operatorIdint[]Filtrar por operadores atribuídos
datestring[]Dois limites: ?date=…&date=…
isChainboolRetornar chats como correntes, transportando mensagens de chats anteriores
isUnread, starMark, isOperator, isAIAgentboolFiltros adicionais
phone, email, contactId, clientId, tagIds, rate, sortedBy—Outros filtros

200 OK retorna GetChatsResponse:

{
  "total": 1,
  "newMessagesCount": 2,
  "items": [
    {
      "id": 1867,
      "theme": null,
      "messSource": 7,
      "chatStatus": 1,
      "countUnread": 2,
      "metaUserId": "1585775752382460",
      "instaAccount": { "id": 12, "name": "my_instagram_shop", "photo": "https://..." },
      "instagramUser": { "id": 123, "name": "marianna_cat", "photo": "https://..." },
      "operator": { "id": 21, "name": "Jane", "photo": "https://..." },
      "client": { "id": 55, "name": "Marianna", "photo": null },
      "textLastMess": "Hello! Is this product available?",
      "timeLastMess": "2026-08-13T10:15:00Z",
      "authorLastMessage": 1,
      "messageStatus": 6,
      "isMedia": false,
      "phone": null,
      "organizationId": 1,
      "createdAt": "2026-08-13T10:14:00Z",
      "isStarred": false,
      "isBlocked": false,
      "tags": []
    }
  ]
}

Os campos importantes para um aplicativo Instagram:

CampoSignificado
instaAccountA conta empresarial do Instagram (a loja). id é o valor do filtro entityId; name é o nome da conta do Meta
instagramUserO cliente**. name é o identificador do Instagram, id é o valor do filtro instagram_user_id
metaUserIdO ID do escopo do cliente no lado do Meta (string)
messSource7 para Instagram
phoneNormalmente null para Instagram — não use como chave

ChatDTO também carrega olxUser, promUser, waba, rozetkaUser, facebookAccount, facebookUser, viberAccount, tgBot, tgUser, viberBot, viberBotUser, widget, media, isConnectedAI, isPromo, rate, rateComment, closedBy, draft, lang, starMark, contactId, contactName, block, isInStopList, stopList, isSmsFallbackEnabled e taggedMessages.

4.2 Mensagens de bate-papo

GET https://chatapi.smsbat.com/api/chat/chats/1867/messages?isChain=false
Authorization: Bearer <token>

200 OK retorna uma matriz de ChatMessageDTO:

[
  {
    "id": 9928,
    "chatId": 1867,
    "message": "Hi! Do you have size M in stock?",
    "messageTranslation": null,
    "phone": null,
    "author": 1,
    "source": 7,
    "media": null,
    "replyTo": null,
    "status": 6,
    "date": "2026-08-13T10:14:00Z",
    "operator": null,
    "client": { "id": 123, "name": "marianna_cat", "photo": "https://..." },
    "messageType": 0,
    "isInternal": false,
    "isBroadcast": false,
    "starMark": false,
    "referralGuid": null,
    "postId": null,
    "isConnectedAI": false,
    "organizationId": 1,
    "countUnreadMessages": 0
  }
]

postId é preenchido quando a mensagem está relacionada a uma postagem ou história do Instagram – passe-a retorne como id / postId para a Meta API. media é um ChatMediaDTO: { name, format, type, uri, raw, length, isUploaded }.

4.3 Enviar uma mensagem (JSON)

POST https://chatapi.smsbat.com/api/chat/1867/message
Authorization: Bearer <token>
Content-Type: application/json

Corpo — SendChatMessageDTO:

{
  "textMessage": "Hello! Yes, size M is available.",
  "author": 0,
  "isInternal": false,
  "replyToMessageId": 9928,
  "appGuid": "550e8400-e29b-41d4-a716-446655440000",
  "media": {
    "name": "item.jpg",
    "format": "image/jpeg",
    "dataBase64": "/9j/4AAQSkZJRg...",
    "type": 1
  }
}
CampoTipoDescrição
textMessagestring?Texto da mensagem. Pode estar vazio quando media estiver presente
authorAuthorMessage?0 operador, 1 cliente
isInternalbool?true marca nota interna que não é entregue ao cliente
replyToMessageIdint?ID da mensagem que está sendo respondida
appGuiduuid?GUID de referência
mediaMediaDTO?{ name, format, dataBase64, thumbnail, duration, type }

200 OK → { "id": 9930, "messageStatus": 0 }

Um GUID de referência também pode ser passado no caminho: POST /api/chat/{chatId}/{referralGuid}/message (da mesma forma …/message/v1, …/message/v2).

4.4 Enviar um arquivo ou vídeo (multipart, v2)

POST https://chatapi.smsbat.com/api/chat/1867/message/v2
Authorization: Bearer <token>
Content-Type: multipart/form-data

Os nomes dos campos do formulário são PascalCase com notação de ponto

textMessage e media.file são ignorados silenciosamente. Use os nomes exatos abaixo.

Campo do formulárioTipoDescrição
TextMessagestringTexto da mensagem
Authorint0 operador, 1 cliente
IsInternalboolNota interna
ReplyToMessageIdintMensagem sendo respondida
AppGuiduuidGUID de referência
Media.FilebinaryO próprio arquivo
Media.NamestringNome do arquivo
Media.FormatstringTipo MIME (video/mp4, image/png, application/pdf)
Media.TypeMediaTypeConsulte §8.5
Media.DataBase64stringAlternativa para Media.File
Media.ThumbnailstringQuadro de visualização de vídeo Base64
Media.DurationdoubleDuração do vídeo em segundos
curl -X POST "https://chatapi.smsbat.com/api/chat/1867/message/v2" \
  -H "Authorization: Bearer <token>" \
  -F "TextMessage=Here is the price list" \
  -F "Author=0" \
  -F "Media.Type=2" \
  -F "Media.File=@./price.pdf"

200 OK → { "id": 9931, "messageStatus": 0 }

4.5 Alterar status do bate-papo

PUT https://chatapi.smsbat.com/api/chat/status
Authorization: Bearer <token>
Content-Type: application/json

{ "id": 1867, "status": 4 }

200 OK ecoa o objeto atualizado.

4.6 Atualizar status de mensagens

PUT https://chatapi.smsbat.com/api/chat/messages/status
Authorization: Bearer <token>
Content-Type: application/json

{ "status": 3, "messageIds": [9928, 9929] }

4.7 Excluir um bate-papo

DELETE https://chatapi.smsbat.com/api/chat/chats/1867
Authorization: Bearer <token>

5. Postagens, Momentos e Histórias

Caminho base: https://chatapi.smsbat.com/api/meta Autorização: X-Authorization-Key: <organization token>

5.1 Listar postagens, Momentos e Histórias

GET https://chatapi.smsbat.com/api/meta/posts?platform=instagram&mediaType=story&page=1&perPage=20
X-Authorization-Key: <token>
ParâmetroTipoObrigatórioDescrição
pageintnãoPágina, padrão 1
perPageintnãoItens por página, padrão 20
idintnãoFiltrar por ID de postagem interna
platformstringnãoinstagram ou facebook
mediaTypestringnãopost, reel ou story. Todos os tipos quando omitidos
# Every post
curl -H "X-Authorization-Key: <token>" \
  "https://chatapi.smsbat.com/api/meta/posts?page=1&perPage=10"

# Instagram only
curl -H "X-Authorization-Key: <token>" \
  "https://chatapi.smsbat.com/api/meta/posts?platform=instagram"

# A single post by ID
curl -H "X-Authorization-Key: <token>" \
  "https://chatapi.smsbat.com/api/meta/posts?id=42"

# Instagram Stories only
curl -H "X-Authorization-Key: <token>" \
  "https://chatapi.smsbat.com/api/meta/posts?platform=instagram&mediaType=story"

200 OK:

{
  "total": 42,
  "items": [
    {
      "id": 42,
      "metaId": "18113450675314072",
      "text": "Check out our new collection!",
      "imageUrl": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-1711-4aa8-b21d-f6dbf8f347ef",
      "platform": "instagram",
      "mediaType": "story",
      "createdAt": "2026-07-22T09:35:30Z",
      "story": {
        "id": 42,
        "metaId": "18113450675314072",
        "url": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-1711-4aa8-b21d-f6dbf8f347ef"
      }
    }
  ]
}

Discrepância — nome do campo do contador

O esquema Swagger MetaCommentPostListItemDtoPaginationDTO define total. O documentos de especificações internas totalCount. Swagger é gerado a partir do código, então total é a verdade mais provável. Analise total ?? totalCount até que isso seja resolvido.

CampoDescrição
idID da postagem interna
metaIdPostagem externa / Reel / ID da história no Meta
textLegenda da postagem
imageUrlURL de mídia proxy codificado pelo não sequencial MetaPost.Guid ou null
platformfacebook ou instagram
mediaTypepost, reel ou story
createdAtData de criação (data da plataforma ou data da base de dados)
storyPresente apenas por mediaType: "story"
story.idID interno da história; igual a post.id
story.metaIdID de história externa em Meta
story.urlURL de proxy estável da mídia Story armazenada; null se a mídia não puder ser salva

A pós-mídia é atendida por duas rotas: GET /api/meta/post/media/{id:int} para trás compatibilidade e GET /api/meta/post/media/{guid:guid}. Novas respostas e retornos de chamada da API sempre gere o formulário GUID.

5.2 Listar comentários

GET https://chatapi.smsbat.com/api/meta/comments?platform=instagram&postId=42&page=1&perPage=20
X-Authorization-Key: <token>
ParâmetroTipoObrigatórioDescrição
pageintnãoPágina, padrão 1
perPageintnãoItens por página, padrão 20
postIdintnãoFiltrar por ID da postagem
parentCommentIdintnãoComentários secundários (respostas) de um determinado comentário
platformstringnãofacebook ou instagram

200 OK:

{
  "total": 100,
  "items": [
    {
      "id": 5,
      "metaId": "179000000000005",
      "text": "What is the price?",
      "createdAt": "2026-04-15T10:30:00Z",
      "platform": "instagram",
      "replyStatus": null,
      "author": {
        "type": "meta_user",
        "name": "John Doe",
        "metaUserId": "1585775752382460"
      },
      "post": {
        "id": 1,
        "metaId": "18113450675314072",
        "text": null,
        "imageUrl": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-…",
        "createdAt": "2026-07-22T09:35:30Z",
        "mediaType": "story",
        "story": {
          "id": 1,
          "metaId": "18113450675314072",
          "url": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-…"
        }
      },
      "mediaUrl": "https://chatapi.smsbat.com/api/meta/comment/media/5",
      "replyTo": {
        "id": 3,
        "metaId": "179000000000003",
        "text": "Parent comment..."
      }
    }
  ]
}
CampoDescrição
idID do comentário interno
metaIdID externo em Meta. null por uma resposta nossa pendente até o seu envio
textTexto do comentário
createdAtData de criação
platformfacebook ou instagram
replyStatusnull para um comentário de usuário recebido; "pending" / "sent" / "failure" pela nossa resposta
author.type"meta_user" usuário externo, "owner" proprietário da página
author.nameNome do autor
author.metaUserIdID do usuário com escopo definido no Meta; null para "owner"
postA postagem, Momento ou História à qual o comentário pertence
post.mediaTypepost, reel ou story
post.storyReferência da história { id, metaId, url }, apenas histórias
mediaUrlMídia anexada ao comentário ou null
replyToComentário pai { id, metaId, text }; null no nível superior

Discrepância — tipo de `author.type`

A especificação interna documenta as strings "meta_user" / "owner". Tipos de arrogância MetaCommentAuthorType como um inteiro com enum [0, 1]. Um JsonStringEnumConverter explicaria a lacuna, mas isso não foi confirmado contra uma resposta real. Escreva um analisador que aceita ambos.

5.3 Responder a um comentário

Enfileira uma resposta para entrega.

curl -X POST \
  -H "X-Authorization-Key: <token>" \
  -H "Content-Type: application/json" \
  -d '{"text": "Thanks for the feedback!"}' \
  "https://chatapi.smsbat.com/api/meta/comments/5/reply"

Corpo da solicitação: { "text": "Reply text" }

202 Accepted retorna o objeto de comentário — mesma forma que GET /api/meta/comments — com replyStatus: "pending" e metaId: null. O resultado da entrega chega mais tarde como um source: 13 retorno de chamada (§6.4).

Discrepância — código de resposta

Swagger declara 200 sem corpo; a especificação interna declara 202 Accepted com o comentário como corpo. O controlador provavelmente não possui um ProducesResponseType atributo, deixando o Swagger em seu padrão. Aceite qualquer 2xx e não dependa de um corpo.


6. Webhooks

SMSBAT envia solicitações POST com application/json para sua URL e espera HTTP 200 de volta.

Campos nulos são totalmente omitidos

Um campo cujo valor é null não é serializado no corpo do retorno de chamada. Por um mensagem que não veio do Facebook ou Instagram simplesmente não existe a chave MetaUserId. Trate “ausente” e null como a mesma coisa.

6.1 Registrar uma URL de retorno de chamada

curl -X POST 'https://restapi.smsbat.com/organizations/callback_urls' \
  -H 'X-Authorization-Key: <token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://your-server.com/webhook",
    "source": 12,
    "headerName": "X-Webhook-Secret",
    "headerValue": "your-secret",
    "channelType": 7,
    "channelEntityId": 12
  }'
CampoTipoDescrição
urlstringSeu ponto final
sourceSendingSourceCallbackTipo de evento, consulte §8.2
headerName / headerValuestringCabeçalho de autenticação arbitrário que anexamos à solicitação (opcional)
channelTypeChatSourceCanal. 7 para Instagram. Opcional
channelEntityIdintUma conta comercial específica. Requer channelType

Sem channelType a URL recebe eventos de todos os canais.

Tip

A cobertura completa dos comentários precisa de dois registros: source: 12 para novos comentários e source: 13 para status de resposta. Para respostas diretas e de histórias, adicione source: 3 (e 11 se quiser todas as mensagens do chat).

Operações restantes:

GET    https://restapi.smsbat.com/organizations/callback_urls?source=12
GET    https://restapi.smsbat.com/organizations/callback_urls/{id}
PUT    https://restapi.smsbat.com/organizations/callback_urls/{id}
DELETE https://restapi.smsbat.com/organizations/callback_urls/{id}

GET retorna:

[
  {
    "id": 101,
    "url": "https://your-server.com/webhook",
    "source": 12,
    "headerName": "X-Webhook-Secret",
    "headerValue": "your-secret",
    "createdAt": "2026-08-13T09:00:00Z",
    "channelType": 7,
    "channelEntityId": 12
  }
]

6.2 Nova mensagem e resposta da história do Instagram (source: 3, 11)

A resposta de um usuário a um Instagram Story chega como uma mensagem comum nesses retornos de chamada, com um bloco Story extra de nível superior:

{
  "ChatId": 123,
  "MessageId": 456,
  "MessageText": "😍",
  "Username": "Jane Smith",
  "UserId": 789,
  "MetaUserId": "1585775752382460",
  "ShopId": 12,
  "ShopName": "instagram shop name",
  "Author": 0,
  "type_messenger": 7,
  "Story": {
    "Id": 42,
    "MetaId": "18113450675314072",
    "Url": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-1711-4aa8-b21d-f6dbf8f347ef"
  }
}
CampoDescrição
ChatId / MessageIdIdentificadores de bate-papo e mensagens
Authorusuário 0, operador 1
UsernameNome de exibição ou identificador do Instagram / Facebook
UserIdID de usuário numérico interno em SMSBAT
MetaUserIdID com escopo do interlocutor no Meta. Em uma mensagem do operador de saída, isso ainda identifica o metausuário do chat, não o operador
ShopIdID interno da conta comercial do Instagram/Facebook
ShopNameNome da conta comercial conforme recebido do Meta no momento da conexão
MessageTextTexto da mensagem
MessageMediaURL de mídia quando a mensagem é mídia
type_messengerFonte, 7 para Instagram
operator_nameNome do operador quando Author = 1
StoryApresentar apenas em uma resposta de história recebida
Story.IdID da história interna (MetaPost) — utilizável diretamente como id / postId na Meta API
Story.MetaIdID de história externa em Meta
Story.UrlURL de proxy estável da mídia Story armazenada. Ausente quando a mídia não pôde ser salva — o bloco Story e a mensagem ainda são entregues

`Author` está invertido em relação à API de bate-papo

Em ChatMessageDTO.author, 0 significa operador e 1 significa cliente. Neste retorno de chamada é o contrário: 0 é o usuário, 1 é o operador. Não compartilhe o mapeamento.

6.3 Novo comentário (source: 12)

Dispara quando um usuário Meta comenta em uma postagem do Facebook ou uma postagem/Reel do Instagram.

Note

Instagram As respostas das histórias não são entregues por meio de source: 12. Elas chegam normalmente mensagens de entrada em source: 3 e/ou 11 com um bloco Story — consulte §6.2.

{
  "type": "new_comment",
  "platform": "instagram",
  "comment": {
    "id": 10,
    "metaId": "179000000000010",
    "parentCommentId": 5,
    "parentMetaId": "179000000000005",
    "parentCommentText": "The user's previous comment",
    "text": "Great product!",
    "createdAt": "2026-04-16T12:00:00Z",
    "author": {
      "type": "meta_user",
      "name": "Jane Smith",
      "metaUserId": "1585775752382460"
    }
  },
  "post": {
    "id": 1,
    "metaId": "123456789012345",
    "text": "Post description...",
    "imageUrl": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-…",
    "createdAt": "2026-04-10T12:00:00Z",
    "mediaType": "post"
  }
}

6.4 Status da resposta do comentário (source: 13)

Dispara depois que tentamos entregar uma resposta, seja ela bem-sucedida ou falha.

{
  "type": "comment_status",
  "platform": "instagram",
  "comment": {
    "id": 15,
    "metaId": "179000000000015",
    "parentCommentId": 10,
    "parentMetaId": "179000000000010",
    "parentCommentText": "Great product!",
    "text": "Thanks for the feedback!",
    "createdAt": "2026-04-16T12:05:00Z",
    "updatedAt": "2026-04-16T12:05:03Z",
    "replyStatus": "sent",
    "author": {
      "type": "owner",
      "name": "Support Agent"
    }
  },
  "post": {
    "id": 1,
    "metaId": "179999999999999",
    "text": "Reel description...",
    "imageUrl": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-…",
    "createdAt": "2026-07-22T09:35:30Z",
    "mediaType": "reel"
  }
}

6.5 Campos de retorno de chamada de comentário compartilhado

Ambos os retornos de chamada de comentários compartilham um formato de corpo e diferem apenas em type.

CampoDescrição
type"new_comment" ou "comment_status"
platform"facebook" ou "instagram"
comment.idID do comentário interno
comment.metaIdID externo em Meta; null para uma resposta pendente antes de ser enviada
comment.parentCommentIdID do comentário pai. Ausente para um comentário de nível superior
comment.parentMetaIdID do comentário pai externo. Ausente no nível superior
comment.parentCommentTextTexto de comentário dos pais. Ausente no nível superior
comment.textTexto do comentário
comment.createdAtData de criação
comment.updatedAtÚltima atualização. Ausente se o comentário nunca foi editado
comment.replyStatus"pending" / "sent" / "failure". Ausente devido a um comentário recebido de um usuário
comment.author.type"meta_user" ou "owner"
comment.author.nameNome do autor
comment.author.metaUserIdID do autor com escopo definido no Meta. Ausente por "owner"
comment.mediaUrlComente a mídia. Ausente quando não há
post.idID da postagem interna
post.metaIdPostagem externa / Reel / ID da história no Meta
post.textPostar texto
post.imageUrlPostar URL da imagem ou null
post.createdAtData de pós-criação
post.mediaTypeEm retornos de chamada de comentários, apenas post ou reel

6.6 Novo bate-papo (source: 7)

{ "ChatId": 12345, "Phone": "+380501234567", "chat.Source": 7 }

6.7 Mudanças no status de mensagens e bate-papo (source: 6 / 5)

{ "name": "changed_message_status", "id": 9928, "status": 6 }
{ "name": "changed_chat_status",    "id": 1867, "status": 4 }

6.8 Mensagem editada ou excluída (source: 9)

{ "messageId": 9930, "text": "Updated message text" }
{ "messageId": 9931, "delete": true }

6.9 Indicador de digitação (source: 8)

{ "chat_id": 1867, "event": "start_typing", "operator_name": "Iryna" }
{ "chat_id": 1867, "event": "end_typing" }

7. Pesquisa de eventos

Para ambientes que não aceitam HTTP de entrada.

7.1 Buscar eventos

GET https://chatapi.smsbat.com/api/chat/callback-events?page=1&perPage=20
Authorization: Bearer <token>
ParâmetroDescrição
organizationIdOpcional. Retirado do token quando omitido
page / perPagePaginação, padrões 1 / 20
{
  "page": 1,
  "perPage": 20,
  "total": 947,
  "items": [
    {
      "ChatId": 1867,
      "MessageId": 9928,
      "MessageText": "Hello there!",
      "MessageMedia": null,
      "Phone": null,
      "Username": "marianna_cat",
      "UserId": 123,
      "ShopId": 12,
      "ShopName": "instagram shop name",
      "Author": 1,
      "type_messenger": 7,
      "message_date": "2026-08-13T12:27:39.724Z",
      "timestamp": "2026-08-13T12:27:39.736Z",
      "event_guid": "ff60129e-c6e4-4876-9d90-badb430c0606",
      "organization_id": 1,
      "callback_type": "3"
    }
  ]
}

Cada evento carrega event_guid, timestamp, organization_id e callback_type — um string correspondente aos valores source em §8.2. Os campos restantes correspondem ao correspondente webhook em §6.

7.2 Reconhecer eventos processados

POST https://chatapi.smsbat.com/api/chat/callback-events/processed
Authorization: Bearer <token>
Content-Type: application/json

[ "ff60129e-c6e4-4876-9d90-badb430c0606" ]

200 OK → { "deleted": 1 }

Os eventos já removidos simplesmente não contam para deleted. Pedidos e novas tentativas são seus responsabilidade do lado.

7.3 Ciclo recomendado

  1. Enquete GET /api/chat/callback-events de acordo com uma programação.
  2. Processe os eventos em seu serviço.
  3. Envie a lista event_guid processada para /callback-events/processed.
  4. Repita.

8. Referência de enumeração

8.1 ChatSource — canal (0–9)

CódigoCanal
0Viber
1ViberBot
2TelegramBot
3Whatsapp
4Widget
5Rozetka
6Facebook
7Instagram
8Baile de formatura
9Olx

8.2 SendingSourceCallback — tipo de evento de retorno de chamada (0–13)

CódigoEvento
3Chat — nova mensagem de bate-papo, incluindo respostas de histórias
5Status do bate-papo alterado
6Status da mensagem alterado
7Novo bate-papo criado
8Indicador de digitação
9Mensagem atualizada ou excluída
11AnyChatMessage — qualquer mensagem de bate-papo
12MetaNewComment — novo comentário no Instagram/Facebook
13MetaCommentStatus — status de entrega da nossa resposta ao comentário

A enumeração abrange 0–13; os valores restantes não são necessários para integrações com Instagram.

8.3 ChatStatus (0–4)

0 Novo, 1 Aberto, 2 Aguardando, 3 Em pausa, 4 Fechado

8,4 MessageStatus (0–11)

CódigoNome
0NOVO
1SUCESSO
2REJEITADO
3LEIA
4DESCONHECIDO
5PROCESSAMENTO
6ENTREGUE
7BLOQUEADO_BY_USER
8USER_NOT_FOUND

A enumeração abrange 0–11. Os valores 9, 10 e 11 existem na API, mas ainda não estão documentados — trate-os como UNKNOWN.

8,5 MediaType (1–10)

1 Foto, 2 Arquivo, 3 Áudio, 4 Vídeo, 5 Adesivo, 6 Adesivo Animado, 7 AdesivoVídeo, 8 Animação, 9 Voz, 10 VídeoNota

8.6 AuthorMessage — autor na API de bate-papo (0–4)

0 Operador, 1 Cliente, 2 Bot, 3 ViberAccount

A enumeração abrange 0–4; o valor 4 não está documentado. Os retornos de chamada de “nova mensagem” usam o mapeamento oposto — ver §6.2.

8,7 ChatMessageType (0–2)

0 Texto, 1 Foto, 2 Arquivo

8.8 Comentário replyStatus

null comentário de usuário recebido, "pending" nossa resposta está na fila, "sent" entregue, "failure" falha na entrega.


Perguntas abertas

Três pontos onde a especificação interna e o Swagger gerado pelo código discordam. Um solicitação com token real liquida todos eles; até então, escreva para o cliente defensivamente.

#PerguntaEspecificaçãoArrogânciaComo verificar
1Cabeçalho de autenticação para /api/meta/*X-Authorization-Keyapenas Bearer declaradocurl -i -H "X-Authorization-Key: <token>" ".../api/meta/posts?perPage=1" — espere 200, não 401
2Campo de contador em respostas MetatotalCounttotalMesma solicitação – leia a chave JSON raiz
3Tipo author.type e código de status reply"meta_user" / "owner", 202 com corpoint [0,1], 200 sem corpocurl -i .../api/meta/comments?perPage=1 mais uma resposta de teste

Orientação provisória:

  • contador — leia total ?? totalCount;
  • author.type — aceita uma string e um número inteiro (0 ↔ meta_user, 1 ↔ owner, mapeamento a ser confirmado);
  • reply — trata qualquer 2xx como sucesso, não requer corpo, obtém o status final do retorno de chamada source: 13.

Notas de implementação

  • A autenticação difere por grupo de endpoints — /api/meta/* usa X-Authorization-Key, bate-papos e os operadores usam Bearer, restapi também aceita.
  • A paginação é escrita de duas maneiras — per_page em /api/chat/chats, perPage em /api/meta/* e /api/chat/callback-events.
  • Os campos multipart/form-data são PascalCase com notação de ponto (Media.File, Media.Type).
  • Campos nulos são omitidos dos retornos de chamada — uma chave ausente significa null.
  • phone geralmente é null no Instagram. Identifique o cliente por instagramUser.id / metaUserId e a loja por instaAccount.id (o valor do filtro entityId).
  • Story.Id de um retorno de chamada pode ser passado diretamente como id / postId para a Meta API.
  • Verifique o expiresAt do JWT do operador antes de usá-lo em um deeplink ou widget.