Esta página é para desenvolvedores que conectam o backend de uma empresa ao Skava. Como um elemento de API é criado e lançado é abordado em Elementos Personalizados: interfaces de API; aqui cobrimos tudo o que precisa acontecer no outro extremo da linha.
A ideia em uma frase: O Skava não conhece o seu domínio. Ele conhece exatamente um formato, o cartão. Você decide o que ele diz, nós apenas verificamos forma, tamanho e segurança. Um pedido de material é um exemplo; a próxima empresa coleta feedback do usuário, a seguinte arquiva uma foto do canteiro de obras em seus próprios registros.
O fluxo em um panorama
- Um administrador da empresa cria um elemento de API no Skava: um formulário mais o endereço, método e token do seu backend.
- Alguém no chat preenche o formulário e o envia.
- O Skava chama o seu backend e envia os valores preenchidos como JSON.
- A sua resposta torna-se o card no chat.
- Opcionalmente, você pode relatar novos estados posteriormente através do callback. Cada relatório torna-se outro card; o anterior permanece.
Requisitos para o seu backend
- HTTPS. Apenas
https://, semhttp, sem credenciais no endereço, no máximo 2000 caracteres. - Acessível publicamente. O host deve resolver exclusivamente para IPs públicos. Localhost, redes privadas, link-local e metadados de nuvem são rejeitados, e isso é verificado em cada chamada.
- Endereço fixo. O Skava resolve o host uma vez e fixa a conexão naquele IP. Uma alteração de DNS durante a chamada não tem efeito.
- Sem redirecionamentos. Um 301 para o endereço "correto" conta como falha. Insira o endereço final imediatamente.
- Tempo de resposta. O tempo limite é configurável por elemento e limitado a 30 segundos. Se precisar de mais tempo, responda imediatamente e reporte o resultado depois através do callback.
- Tamanho da resposta. O Skava lê no máximo 256 KiB.
- Content-Type. O corpo é analisado apenas com
application/json.
A solicitação que chega até você
O método é GET, POST, PUT ou PATCH, dependendo do elemento. Com POST, PUT e PATCH, os valores chegam como um corpo JSON; com GET, como parâmetros de consulta.
A autenticação é um único cabeçalho cujo nome e prefixo de valor são configurados no elemento, geralmente Authorization com o prefixo Bearer . O token é armazenado criptografado em nosso lado. Os cabeçalhos host, content-length, content-type, cookie e accept-encoding não podem ser definidos.
O corpo é um objeto plano. As chaves são escolhidas por quem construiu o elemento; aninhamento aparece apenas onde foi adicionada uma tabela ou um seletor de produto:
{"artikelnummer": "5100110", "menge": 20, "note": "Please deliver in the morning", "orderer": "Jonas Berger", "company": "Sanitar Berger GmbH", "project": "Spitalstrasse 11", "locale": "de", "callback_url": "https://chat.skava.io/api/v1/custom-elements/interactions/…", "callback_token": "…"}
Três chaves sempre vêm de nós, portanto não as utilize:
- locale: o código de idioma do usuário. Responda nesse idioma; nós não traduzimos seus textos.
- callback_url e callback_token: o callback para esta interação, veja abaixo. Eles só estão presentes quando a chamada vem de um chat.
Campos de contexto como name, company, project ou subchat são preenchidos pelo próprio servidor, derivados do canal em que o elemento foi executado. Um cliente adulterado não pode alegar um nome de projeto diferente ali.
A resposta: o formato do cartão
Responda com 2xx e um objeto card. É exatamente isso que se torna o cartão no chat:
{"card": {"v": 1, "title": "Order BST-10001", "state": "pending", "status_text": "Order received", "icon": "package", "fields": [{"label": "Order number", "value": "BST-10001"}, {"label": "Expected", "value": "14/08/2026"}]}}
- v (obrigatório): o inteiro
1. Como texto ("1") é rejeitado. Sem ele, a resposta não conta como cartão e aplica-se o mapeamento de resposta configurado no elemento. - title: o título do cartão.
- state: apenas cor e tom do ícone, um de
ok,pending,warn,error. Um valor desconhecido recorre aoke você recebe uma dica. - status_text: texto livre que não interpretamos. Fica no topo do cartão e também é o que aparece na lista de chats e em uma notificação push.
- fields: uma lista de
labelevalue. No máximo 20 entradas,label80 caracteres,value200,titleestatus_text120 cada. Valores muito longos são encurtados, não rejeitados: um pedido não deve falhar por causa de um detalhe. - icon: veja abaixo.
O que o Skava faz com seus textos antes de chegarem ao chat: quebras de linha e caracteres de controle são removidos (um caractere de direita para esquerda poderia inverter a exibição de um valor), crases são substituídas e tudo que começa com [SKAVA: é neutralizado. O último impede que um valor de cartão seja lido como um elemento de chat diferente, por exemplo, um pedido de pagamento.
Links em campos, HTML e imagens não podem ser definidos. Um chat é um ambiente confiável e um endereço clicável de uma origem externa seria um convite para reconstruir uma página de login.
As entradas do usuário pertencem ao servidor: aparecem no primeiro cartão e você não pode sobrescrevê-las. No chat, elas são o registro do que foi realmente enviado.
Ícones
Com icon, o cartão ganha sua própria marca no cabeçalho. Duas formas:
Um nome do conjunto incluído: package, package-check, package-open, box, boxes, truck, forklift, warehouse, settings, cog, gauge, wrench, hammer, drill, hard-hat, ruler, paint-roller, construction, clipboard-check, receipt, file-text, camera, clock, calendar-clock, circle-check, circle-alert, triangle-alert, send, mail-check, shopping-cart, credit-card, map-pin.
Ou seu próprio SVG como uma string. A partir dele, a Skava extrai apenas a geometria (path, circle, ellipse, rect, line, polyline, polygon com seus atributos numéricos) e constrói sua própria imagem. Scripts, estilos, referências externas, foreignObject e atributos de eventos são descartados; um doctype ou entidade leva à rejeição; o arquivo pode ter no máximo 8 KiB e conter no máximo 16 formas. Cor, largura do traço e tamanho são definidos pela Skava, portanto um ícone não pode se disfarçar de controle. Trabalhe com uma grade de 24 por 24.
Sem icon, a marca padrão permanece.
O callback: relatar estados posteriores
A chamada contém callback_url e callback_token. Use-os para relatar novos estados posteriormente:
POST <callback_url> com Authorization: Bearer <callback_token> e Content-Type: application/json, corpo de no máximo 32 KiB:
{"card": {"v": 1, "title": "Order BST-10001", "state": "pending", "status_text": "Shipped", "icon": "truck", "fields": [{"label": "Tracking number", "value": "DPD123456789"}]}, "seq": 3, "final": false}
Além do cartão, existem três valores opcionais:
- seq: seu próprio contador. Um relatório com um valor menor ou igual é descartado para que dois relatórios não se sobreponham. Sem
seq, o último a chegar prevalece. - final: encerra a interação. O token torna-se inválido e nenhum outro cartão aparece. Também permitido na resposta first, para fluxos sem acompanhamento.
- notify: defina como
falsepara publicar o cartão silenciosamente, sem contagem de não lidos e sem notificação. Ideal para etapas intermediárias que não devem acordar ninguém. Sem isso, o cartão é uma mensagem perfeitamente normal.
Cada relatório se torna seu próprio cartão no chat, mantendo o anterior. Assim, fica claro qual estado foi relatado. Daí a recomendação: envie apenas o que mudou. Um cartão que repete número do pedido, itens e total pela quarta vez é apenas ruído para o leitor.
Dois limites: o mesmo relatório duas vezes não gera um segundo cartão, e uma interação pode publicar no máximo 50 cartões. Uma interação aceita relatórios por 90 dias.
Respostas às quais você deve reagir
200com{"result": "success", "updated": true, "seq": 3, "closed": false, "hints": []}. Leia as dicas: elas indicam o que foi encurtado ou descartado.401: token ou ID de interação incorretos. Não tente novamente.410: interação encerrada ou expirada. Não tente novamente.422: cartão inutilizável, comhintscomo motivo. Corrija primeiro.400JSON inválido,413muito grande,429muitas solicitações (tente novamente com back-off),500nossa falha, tente mais tarde.
Exemplo 1: um pedido com histórico de status
Passo 1, a solicitação ao seu backend:
POST https://api.example.com/v1/orders
Authorization: Bearer <your token>
{"artikelnummer": "5100110", "menge": 20, "orderer": "Jonas Berger", "company": "Sanitar Berger GmbH", "locale": "de", "callback_url": "https://chat.skava.io/api/v1/custom-elements/interactions/1111…", "callback_token": "secret"}
Passo 2, sua resposta imediata:
{"card": {"v": 1, "title": "Order BST-10001", "state": "pending", "status_text": "Order received", "icon": "package", "fields": [{"label": "Order number", "value": "BST-10001"}, {"label": "Expected", "value": "14/08/2026"}]}}
O chat agora exibe um cartão com um ícone de pacote, o status e as entradas do usuário.
Passo 3, mais tarde durante a separação:
POST <callback_url> to {"card": {"v": 1, "title": "Order BST-10001", "state": "pending", "status_text": "Being picked", "icon": "cog", "fields": []}, "seq": 2, "notify": false}
Um segundo cartão silencioso sem campos: apenas o status mudou.
Passo 4, no envio:
POST <callback_url> to {"card": {"v": 1, "title": "Order BST-10001", "state": "pending", "status_text": "Shipped", "icon": "truck", "fields": [{"label": "Tracking number", "value": "DPD123456789"}, {"label": "Carrier", "value": "DPD"}]}, "seq": 3}
Este cartão pode acordar alguém, portanto sem notify: false.
Passo 5, na entrega:
POST <callback_url> to {"card": {"v": 1, "title": "Order BST-10001", "state": "ok", "status_text": "Delivered", "icon": "package-check", "fields": []}, "seq": 4, "final": true}
Com final a interação é encerrada e o token não funciona mais.
Exemplo 2: uma ação sem acompanhamento
Nem todo fluxo tem histórico. Um elemento com um único campo que envia algo para o seu sistema precisa apenas de uma resposta:
{"card": {"v": 1, "title": "Filed", "state": "ok", "status_text": "Stored under project 4711", "icon": "clipboard-check", "fields": [{"label": "Case", "value": "4711"}]}, "final": true}
final: true é importante aqui: caso contrário, a interação permaneceria aberta por 90 dias com um token válido, mesmo que você nunca mais reporte nada.
Seletor de produtos do catálogo
Depois que a empresa carregar seu catálogo de artigos, o elemento pode conter o bloco seletor de produtos. O usuário monta um carrinho a partir dele e você o recebe como uma lista sob a chave escolhida por quem criou o elemento:
{"items": [{"artikelnummer": "5100110", "menge": 20}, {"artikelnummer": "5100111", "menge": 2}], "note": "…"}
Como a chave é gratuita, procure a primeira lista com esse formato em vez de um nome fixo. Antes de enviar, o Skava verifica se cada número realmente existe no catálogo da empresa, no máximo 50 itens. No cartão, os itens aparecem como uma lista com imagem do produto, nome e quantidade.
Teste
- Ping no editor de elementos envia um
HEADsimples sem token e sem dados. Responda com qualquer coisa; qualquer resposta HTTP conta como acessível. - Solicitar teste executa uma chamada real com valores de exemplo, mesmo enquanto o elemento ainda é um rascunho, e mostra a solicitação, a resposta e as mensagens do validador de cartão.
- Visualização na aba ao lado: cole seu JSON de resposta, verifique e você verá o cartão finalizado além das dicas. Ele é verificado no servidor com o mesmo código usado em produção.
- Exemplo de servidor: um exemplo completo de fornecedor está em execução em
api.skava.ioe utiliza tudo o que foi descrito acima. O seu código-fonte encontra-se no repositório emexample_order_server/, cerca de 600 linhas de biblioteca padrão pura, destinado a ser copiado.
O que mais deve saber
- O cartão é uma mensagem de chat perfeitamente normal. Aparece na pesquisa, pode ser citado e permanece no histórico.
- É enviado pelo remetente do sistema, não por uma conta da sua empresa. Ainda assim, aparece do lado de quem executou o elemento, e o sistema que está a escrever é indicado no título.
- Quem pode executá-lo é definido no elemento: apenas membros da empresa ou também pessoas externas que partilham um chat com ela. Quando a sua empresa sai do chat, a permissão termina automaticamente.
- Um elemento de API com token expirado fica inativo e nem aparece no menu até que um administrador armazene um novo.
Relacionado
Criar e publicar: Elementos personalizados: interfaces de API. Documentos preenchíveis em vez de interfaces: Elementos personalizados: documentos.