Meeto Widget: documentação para desenvolvedores

O widget é um iframe do meeto.me com uma ponte postMessage tipada. Tudo o que você precisa é de uma chave pública de embed — crie uma no painel.

Início rápido

Escolha o seu stack, substitua YOUR_KEY pela sua chave e dê uma altura ao contêiner — o widget preenche 100% dele.

<div id="meeto-call" style="height: 520px"></div>
<script src="https://meeto.me/widget.js" data-key="YOUR_KEY" data-target="#meeto-call"></script>

Pacotes npm: @meeto/embed-core (sem dependências), @meeto/embed-react, @meeto/embed-vue, @meeto/embed-angular. O script comum widget.js funciona sem nenhuma etapa de build.

Parâmetros do script

Atributos da tag <script src="https://meeto.me/widget.js"> (* — obrigatório). As mesmas opções existem na API JavaScript (key, container, room, name, lang, accent, autoJoin, baseUrl) e como atributos do web component <meeto-room>.

ParâmetroDescrição
data-key*Chave pública de embed (mk_live_…) do painel.
data-modeinline (padrão, iframe no seu contêiner) ou bubble — um botão de chamada flutuante no canto da página; não precisa de contêiner.
data-targetSeletor CSS do contêiner. Sem ele, um bloco de 520px de altura é criado logo após a tag do script.
data-room-nameSala nomeada permanente: todos com este trecho entram na mesma sala («support»). O dono da chave entra como host pelo painel.
data-positionCanto do balão: bottom-right (padrão) ou bottom-left.
data-labelaria-label do botão do balão (o widget não conhece o idioma do seu site).
data-roomCódigo de uma sala existente (meeto.me/<code>). Sem ele, o widget cria uma sala sozinho e a reutiliza dentro da aba.
data-nameNome do participante preenchido antecipadamente no lobby.
data-langIdioma da interface do widget (en, ru, de, …). Padrão — o idioma do navegador do visitante.
data-accentCor de destaque, hex (ex.: #27D6AA).
data-auto-joinPule o lobby e entre imediatamente (apenas salas de porta aberta; câmera e microfone começam ativados).
data-base-urlEndereço do Meeto para instalações self-hosted.
data-acceleratedIncorporação pronta para isolamento, servida a partir de call.meeto.me: efeitos de câmera mais rápidos quando sua página está isolada de outras origens (cabeçalhos COOP/COEP). Sem esses cabeçalhos, o widget funciona exatamente como a incorporação padrão.

Os links das salas continuam válidos: qualquer sala do widget também pode ser aberta em meeto.me/<code>.

Eventos e métodos

Inscreva-se via widget.on(type, handler) (retorna uma função de cancelamento), a opção onEvent, as props dos componentes de framework ou os CustomEvents meeto:* do elemento <meeto-room>.

const widget = new MeetoWidget({ key: "mk_live_…", container: "#call" });
const off = widget.on("joined", (e) => console.log(e.room));
widget.on("participants", (e) => console.log("in call:", e.count));
EventoPayload
ready— — o widget carregou e se conectou à página
phase{ phase: "prejoin" | "room" | "finished" | "error" } — a tela mudou (lobby, call, finished, error)
joined{ room, identity } — o visitante entrou na chamada
left{ reason, durationSec } — o visitante saiu da chamada (reason: left, ended, kicked, connection)
participants{ count } — a contagem de participantes mudou
error{ code, message } — o widget não consegue iniciar (chave inválida, domínio não registrado, …)

Métodos da instância do widget:

MétodoDescrição
join(name?)Entre na chamada a partir do lobby de forma programática (salas de porta aberta).
leave()Saia da chamada.
setMicrophone(on)Ligue/desligue o microfone durante a chamada.
setCamera(on)Ligue/desligue a câmera durante a chamada.
destroy()Remova o iframe e todas as inscrições.

Em uma sala em que é preciso bater na porta, com senha ou bloqueada, join() mantém o visitante no lobby e o widget emite error com o código join_not_allowed — em vez disso, deixe o visitante entrar sozinho pelo lobby.

API de servidor

Para fluxos no lado do servidor (criar salas a partir do seu backend, enviar links por e-mail, decidir quem vira anfitrião) use a chave secreta mk_secret_… — ela é mostrada uma vez, quando você cria o embed:

curl -X POST https://api.meeto.me/api/embed/rooms \
  -H "Authorization: Bearer mk_secret_…"
# → 201 { "slug": "misty-fox-42", "hostSecret": "…" }
curl -X POST https://api.meeto.me/api/v1/meetings \
  -H "Authorization: Bearer mk_secret_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: appointment-872" \
  -d '{
    "title": "Project review",
    "startsAt": "2027-03-22T10:00:00+02:00",
    "durationMin": 45,
    "timezone": "Europe/Tallinn"
  }'
# → 201 { "meeting": { "id": "…", "joinUrl": "https://meeto.me/…?k=…" }, "hostSecret": "…" }

curl https://api.meeto.me/api/v1/meetings \
  -H "Authorization: Bearer mk_secret_…"

hostSecret torna quem a possui o anfitrião da sala: passe a sala ao widget via data-room e entregue hostSecret apenas à sua própria equipe. Requisições com a chave secreta pulam a verificação de domínio — nunca a exponha em código de navegador.

A API versionada (/api/v1) está disponível no plano Pro: solicitações com a chave de uma conta Free recebem 402 plan_required. O widget em si funciona em todos os planos.

SDKs móveis (iOS / Android)

Wrappers nativos incorporam o mesmo widget ao seu app: uma WebView com uma ponte tipada de eventos/comandos. Registre a origem do app app://<bundle-id> nos domínios da chave.

iOS (Swift Package, iOS 14+)

// Xcode → File → Add Package Dependencies…
https://github.com/meeto-app/meeto-widget-ios.git   // from: 0.1.2
import MeetoWidget

MeetoWidget(config: .init(key: "mk_live_…", roomName: "support")) { event in
    if event.type == "left" { /* close the screen */ }
}

Swift Package; adicione NSCameraUsageDescription e NSMicrophoneUsageDescription ao Info.plist.

Android (Kotlin, minSdk 24)

// settings.gradle.kts
dependencyResolutionManagement { repositories { maven("https://jitpack.io") } }

// module's build.gradle.kts
dependencies { implementation("com.github.meeto-app:meeto-widget-android:0.1.3") }
val widget = MeetoWidgetView(this)
widget.onEvent = { event -> if (event.type == "left") finish() }
container.addView(widget)
widget.load(MeetoWidgetConfig(key = "mk_live_…", roomName = "support"))

Módulo Gradle; declare CAMERA / RECORD_AUDIO / INTERNET e solicite as permissões em tempo de execução antes de exibir o widget.

Eventos (ready, joined, left, participants, error) e comandos (join, leave, setMicrophone, setCamera) são idênticos ao SDK web.

Código-fonte e lançamentos: meeto-app/meeto-widget-ios ↗meeto-app/meeto-widget-android ↗

Plugin do WordPress

Adicione o widget a um site WordPress sem escrever código: um botão de chamada flutuante em cada página ou uma chamada incorporada via shortcode.

Baixar meeto-widget.zip
  1. No painel do WordPress, abra Plugins → Adicionar novo → Enviar plugin e faça o upload do zip.
  2. Ative o plugin e abra Configurações → Meeto Widget.
  3. Cole sua chave de incorporação (com o domínio do seu site adicionado a ela) — o botão de chamada está ativo.

Para um widget incorporado, desative a inserção automática nas configurações e coloque o shortcode em qualquer página: [meeto_widget room_name="support" height="600"]

Limites

As salas do widget seguem o plano do dono da chave:

  • Free — até 10 participantes, chamadas em grupo de até 60 minutos, até 1080p.
  • Pro — até 25 participantes, sem limite de tempo para 2 reuniões simultâneas e até 4K em desktops compatíveis. A marca Meeto continua visível.

Segurança

  • A chave pública não é um segredo: ela fica visível no código-fonte da sua página, e isso é proposital.
  • O widget só funciona em domínios registrados para a chave. O navegador informa a origin do site que faz a incorporação de um jeito que as páginas não conseguem forjar (postMessage event.origin), e o backend do Meeto verifica isso.
  • A chave secreta mk_secret_… é armazenada com hash e mostrada apenas uma vez. Use-a exclusivamente de servidor para servidor.
  • Uma chave vazada ou sem uso pode ser revogada no painel a qualquer momento — o widget para na hora.

Perguntas frequentes

Quais frameworks são suportados?

Qualquer um. HTML puro via widget.js, React/Next.js, Vue/Nuxt e Angular via pacotes npm, e todo o resto via o web component <meeto-room>.

Funciona com um Meeto self-hosted?

Sim: aponte data-base-url (ou a opção baseUrl) para a sua instalação.

Posso remover o “Powered by Meeto”?

Não. O selo “Powered by Meeto” continua visível em todos os planos, incluindo Pro e Team.

Quais tamanhos o widget suporta?

Qualquer um: o iframe preenche o contêiner. Em contêineres estreitos, a interface muda automaticamente para o layout compacto.