---
title: OpenAPI / AsyncAPI
description: >-
  Adicione uma especificação OpenAPI ou AsyncAPI e obtenha uma referência de API nativa — uma página real por operação, na sua barra lateral e na busca.
---

Aponte o Blume para uma especificação OpenAPI e ele gera uma referência de API nativa: uma **página real por operação**, agrupada por tag em uma barra lateral delimitada por aba, com tabelas de esquema, exemplos de requisição/resposta, amostras de código geradas e um painel interativo [Try it](#try-it-playground). Como cada operação é uma página Blume genuína, ela ganha sua própria URL, aparece na **busca do site** e no `llms.txt`, e recebe uma imagem Open Graph — igual a qualquer documento escrito à mão. A configuração abaixo aponta o Blume para a especificação pública do Petstore como exemplo.

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  spec: "https://petstore3.swagger.io/api/v3/openapi.json",
}
```

Isso monta a referência em `/reference` (uma página de visão geral) com cada operação em `/reference/<tag>/<operation>`. O `spec` é uma URL `http(s)` ou um caminho para um arquivo local no seu projeto. O Blume o analisa com o [parser OpenAPI do Scalar](https://github.com/scalar/scalar) — especificações Swagger 2.0 e OpenAPI 3.0 são atualizadas para 3.1 automaticamente. Está documentando uma API GraphQL? Veja a [referência GraphQL](/docs/advanced/graphql).

A referência não adiciona uma aba de cabeçalho por conta própria. Para exibi-la, aponte uma [aba de navegação](/docs/content/navigation#tabs) para sua rota — isso também delimita a barra lateral de operações para o renderizador nativo:

```ts blume.config.ts
navigation: {
  tabs: [{ label: "API", path: "/reference" }],
}
```

:::note
As operações são indexadas para busca pelo seu **resumo e tag**. As tabelas de esquema renderizadas e as amostras de código não são indexadas em texto completo; a busca corresponde ao título e à seção de uma operação e, em seguida, cria um link para sua própria página.
:::

## Uma especificação local [#a-local-spec]

Um caminho relativo é resolvido a partir da raiz do seu projeto e lido em tempo de build. Tanto JSON quanto YAML funcionam:

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  spec: "./openapi.yaml",
}
```

## Rota [#route]

`route` controla onde a referência é montada — a página de visão geral e o prefixo para cada rota de operação (e a rota para a qual você aponta uma aba de navegação):

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  route: "/api",   // overview at /api, operations at /api/<tag>/<operation>
  spec: "./openapi.yaml",
}
```

## Amostras de código e esquemas [#code-samples-and-schemas]

`codeSamples` escolhe quais linguagens são renderizadas por operação (nativas: `curl`, `js`, `python`); `expandSchemas` inicia as linhas de esquema aninhadas expandidas em vez de recolhidas:

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  spec: "./openapi.yaml",
  codeSamples: ["curl", "js"],
  expandSchemas: true,
}
```

## Playground Try it [#try-it-playground]

Páginas de operação renderizadas nativamente vêm com um painel interativo **Try it** por padrão. O Blume gera o formulário a partir da própria operação: um campo por parâmetro de caminho, consulta e cabeçalho, um editor de corpo construído a partir do esquema do corpo da requisição, tudo pré-preenchido a partir dos exemplos da especificação. Um seletor de servidor lista os `servers` da especificação, com um campo de texto livre para qualquer outra URL base, e os campos de autenticação correspondem à [segurança resolvida](#authorization) da operação — token bearer, chave de API e credenciais basic, com OAuth2 como um campo para colar o token (traga um token de acesso; o Blume não executa o fluxo).

O painel e as amostras de código andam em sincronia: valores digitados no formulário atualizam as amostras geradas ao vivo, então um comando curl copiado sempre corresponde exatamente ao que o **Send** faria. E ele fica fora do caminho — o painel é renderizado no servidor já recolhido, e seu JavaScript é carregado apenas quando um leitor o abre pela primeira vez. Leitores que nunca o tocam não baixam nada disso.

`playground: false` é todo o interruptor de desligamento:

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  spec: "./openapi.yaml",
  playground: false,
}
```

### Credenciais [#credentials]

As credenciais digitadas nos campos de autenticação ficam na memória e desaparecem ao recarregar. Marcar **Remember on this device** as persiste no `localStorage`, delimitado à origem da documentação — elas nunca são enviadas para lugar nenhum além da API que está sendo chamada. As amostras de código continuam exibindo espaços reservados (`YOUR_TOKEN` e companhia) independentemente do que for digitado, a menos que o leitor ative **Include my values in samples**.

### CORS e o proxy [#cors-and-the-proxy]

Assim como no [renderizador Scalar](#the-scalar-renderer), as requisições vão **diretamente do navegador** para a API de destino, então a API precisa permitir requisições de origem cruzada a partir do site de documentação (`Access-Control-Allow-Origin`). Para APIs que não podem, defina `playground.proxy`: uma URL roteia as requisições através de um proxy hospedado por você, e `true` habilita a rota interna `/_api-proxy` — que precisa de um build de servidor, então exige [`deployment.output: "server"`](/docs/deployment#server-rendering):

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  spec: "./openapi.yaml",
  playground: {
    proxy: true,   // or a URL of your own
  },
}
```

O proxy interno só encaminha requisições para as origens que suas especificações declaram em `servers` — inclusive através de redirecionamentos — então uma implantação pública de documentação não pode ser apontada para outros hosts na sua rede. Uma **Custom base URL** digitada no painel não é um servidor documentado: com o proxy habilitado, requisições para ela são recusadas com um 403.

## Múltiplas especificações [#multiple-specs]

Use `sources` para publicar mais de uma especificação. Cada fonte recebe sua própria rota de visão geral, páginas de operação e aba de cabeçalho. Dê a cada uma um `label` (usado para a aba e para derivar sua rota), ou defina uma `route` explícita:

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  sources: [
    { label: "Public API", spec: "./public.json" },   // → /reference/public-api
    { label: "Admin API", route: "/admin", spec: "./admin.json" },
  ],
}
```

`spec` é um atalho para um `sources` de entrada única, então você só recorre a `sources` quando tem mais de uma.

### Indexação por fonte [#per-source-indexing]

As páginas geradas participam da busca, do `llms.txt` e da indexação por rastreadores por padrão. Uma especificação secundária ou sobreposta pode optar por sair de qualquer superfície sem ocultar suas páginas ou removê-la da navegação:

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  sources: [
    { label: "Public API", route: "/api", spec: "./public.json" },
    {
      label: "Platform API",
      route: "/platform",
      spec: "./platform.json",
      includeInSearch: false,
      includeInLlms: false,
      noindex: true,
    },
  ],
}
```

- `includeInSearch: false` mantém a visão geral e as operações da fonte fora da busca do site.
- `includeInLlms: false` as mantém fora de ambos os arquivos `llms.txt`.
- `noindex: true` adiciona metadados noindex para rastreadores e remove as páginas do sitemap.

A meta descrição de cada página de operação é a própria `description` da operação (ou o `summary`), seguida de uma frase gerada que nomeia o endpoint — "Reference for the `GET /pets` endpoint in the Petstore API." — então uma especificação com resumos secos de uma linha ainda entrega uma descrição distinta e do tamanho de um snippet por página. Essa frase está em inglês. Em um site cuja prosa da especificação está escrita em outro idioma, defina `seoDescriptionSuffix: false` na fonte para descartá-la e descrever cada página apenas com a prosa autoral; uma operação sem `description` nem `summary` recorre ao seu título (`GET /pets`), então nenhuma página é entregue com uma descrição vazia:

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  sources: [{ spec: "./openapi.de.json", seoDescriptionSuffix: false }],
}
```

Com o [renderizador Scalar](#the-scalar-renderer), apenas `noindex` se aplica — uma referência renderizada pelo Scalar já fica fora da busca e do `llms.txt` do Blume, então as duas configurações `include*` não têm sobre o que atuar ali.

## Autorização [#authorization]

Operações que declaram [requisitos de segurança](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) renderizam uma seção **Authorization** acima de seus parâmetros, e as amostras de código geradas enviam uma credencial de espaço reservado (`Authorization: Bearer YOUR_TOKEN`, um cabeçalho de chave de API ou uma chave de consulta — o que o esquema exigir). Não há nada para configurar: o Blume lê `security` da especificação, então a referência sempre corresponde ao que a API realmente aplica.

A semântica do OpenAPI é mantida conforme escrita:

- O `security` próprio de uma operação sobrescreve o padrão da raiz do documento; `security: []` a marca como **pública** e não renderiza nenhuma seção de Autorização.
- Múltiplas entradas de requisito são alternativas — renderizadas como grupos "ou"; todos os esquemas dentro de uma entrada são exigidos em conjunto. A primeira alternativa alimenta as amostras de código.
- Uma entrada `{}` vazia significa que a autenticação é **opcional** para aquela operação, e a seção informa isso.
- Os escopos OAuth2 são listados por esquema; as `description`s de esquema de `components.securitySchemes` são renderizadas inline.

## O renderizador Scalar [#the-scalar-renderer]

O renderizador nativo é o padrão — as páginas de operação, a integração com a busca e o [playground Try it](#try-it-playground) acima são todos obra dele. Se você preferir incorporar a interface de referência de API autocontida do [Scalar](https://scalar.com) — com sua própria barra lateral, busca, tema e cliente de requisições em uma única rota — defina `renderer: "scalar"`:

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  renderer: "scalar",
  spec: "./openapi.yaml",
  theme: "purple",   // a Scalar theme name (Scalar renderer only)
}
```

Uma referência renderizada pelo Scalar é uma incorporação autocontida em sua própria rota — ela não se integra à barra lateral, à busca ou ao `llms.txt` do Blume, e a configuração [`playground`](#try-it-playground) do Blume não se aplica a ela. O que ela segue é o alternador claro/escuro do Blume: a incorporação é fixada no tema da página quando é montada e muda junto com ele, então o alternador de tema do próprio Scalar fica oculto (defina `scalar.forceDarkModeState` ou `scalar.darkMode` para devolver o controle do modo de cor ao Scalar). O Scalar traz seu próprio cliente de requisições, que chama sua **API de destino diretamente do navegador** (a rota `playground.proxy` não está disponível aqui), então a API precisa permitir requisições de origem cruzada a partir do site de documentação (`Access-Control-Allow-Origin`). `theme` se aplica apenas ao renderizador Scalar.

### Passando opções do Scalar [#passing-scalar-options]

`theme` é um atalho para a opção que a maioria das pessoas usa, mas o Scalar suporta muitas outras. Um objeto `scalar` encaminha qualquer [configuração do Scalar](https://github.com/scalar/scalar/blob/main/documentation/configuration.md) diretamente para a referência incorporada — o Blume não restringe as chaves, então tudo o que o Scalar aceita passa adiante:

```ts blume.config.ts lineNumbers
openapi: {
  enabled: true,
  renderer: "scalar",
  spec: "./openapi.yaml",
  scalar: {
    localization: { locale: "es" },   // translate Scalar's own UI
    agent: { disabled: true },         // disable the Scalar Agent
    hideTestRequestButton: true,
    orderSchemaPropertiesBy: "preserve",
  },
}
```

O [`i18n`](/docs/content/i18n) do próprio Blume traduz a interface da documentação, mas o Scalar tem um sistema de localização separado — defina `scalar.localization.locale` para traduzir também a referência incorporada. As opções no objeto `scalar` prevalecem sobre a configuração derivada do Blume, então tudo que for definido aqui (incluindo `theme`, `customCss` ou o `content`/`url` da especificação) sobrescreve os padrões do Blume. O mesmo bloco `scalar` funciona na referência `asyncapi`.

## AsyncAPI

APIs orientadas a eventos usam um bloco irmão `asyncapi` com o mesmo formato — e o mesmo renderizador nativo. Cada operação `send`/`receive` se torna uma página real com tabelas de esquema do payload e dos cabeçalhos da mensagem, parâmetros de canal, bindings de protocolo, uma seção de Autorização derivada dos `securitySchemes` da especificação (em nível de servidor e de operação, com alternativas como grupos "ou") e um compositor de mensagens [Try it](#try-it-for-events). Apenas a rota padrão difere (`/events`):

```ts blume.config.ts lineNumbers
asyncapi: {
  enabled: true,
  spec: "./asyncapi.yaml",
}
```

Especificações AsyncAPI **2.x são normalizadas para 3.x automaticamente** com o conversor oficial do AsyncAPI, então canais `publish`/`subscribe` são mapeados para páginas de operação `send`/`receive` com URLs estáveis — atualizar mais tarde o próprio arquivo de especificação através do conversor não move nada. As operações são agrupadas por tag; operações sem tag são agrupadas sob o endereço do seu canal.

As amostras de código são **sensíveis ao protocolo**, derivadas do binding da operação (ou do protocolo dos seus servidores): `wscat` e um snippet de `WebSocket` do navegador para WebSockets, `kcat` para Kafka, `mosquitto_pub`/`mosquitto_sub` para MQTT. `codeSamples` filtra esse conjunto, da mesma forma que escolhe linguagens no bloco `openapi`; um protocolo sem uma ferramenta suportada renderiza apenas o exemplo de payload da mensagem em vez de um cliente fabricado.

Tudo o que foi documentado acima se mantém, incluindo o [`playground`](#try-it-for-events): `route`, `sources` com `label`/`route`, `expandSchemas`, as flags de [indexação por fonte](#per-source-indexing) (`seoDescriptionSuffix` também — a frase gerada nomeia o canal e a ação em vez de um endpoint) e a indexação de busca por resumo e tag da operação.

Definir `renderer: "scalar"` volta a optar pelo SPA incorporado do Scalar, onde — como no OpenAPI — apenas `noindex` se aplica. O Scalar não tem um playground AsyncAPI próprio; sua incorporação detecta automaticamente o tipo de documento e renderiza canais, operações, mensagens e uma seção de Modelos, então essa troca abre mão do compositor.

### Try it para eventos [#try-it-for-events]

Páginas de operação renderizadas nativamente também vêm com um painel **Try it** aqui, nos mesmos termos do [painel OpenAPI](#try-it-playground): renderizado no servidor já recolhido, com seu JavaScript carregado apenas quando um leitor o abre pela primeira vez.

Seja qual for o protocolo, o painel abre com um editor de payload pré-preenchido a partir dos `examples` da mensagem — ou, quando a mensagem não declara nenhum, a partir de um valor amostrado do esquema do payload — validado contra o esquema de payload da mensagem conforme você digita. Abaixo dele ficam um campo por parâmetro de canal e um seletor de servidor alimentado pelos `servers` do canal, com um campo de texto livre para qualquer outra URL. As amostras de código sensíveis ao protocolo andam em sincronia com o formulário exatamente como curl, js e python fazem em uma operação HTTP: o template de endereço do canal é preenchido com os valores de parâmetro que você digita, então um snippet copiado de `wscat`, `WebSocket`, `kcat` ou `mosquitto_pub` corresponde ao que o formulário diz.

A conexão ao vivo é exclusiva para WebSocket. Em um binding `ws` ou `wss`, o painel se conecta à URL de canal resolvida, mostra o estado da conexão e registra cada frame com um timestamp. O AsyncAPI 3 declara uma ação do ponto de vista da API, e o painel segue isso: uma operação `receive` é uma que a API recebe de você, então ela ganha um botão **Send** que publica o payload composto; uma operação `send` apenas transmite mensagens para você, então ela se conecta e registra. Não há lógica de reconexão — uma vez que um socket fecha, ele permanece fechado até você conectar novamente. Kafka, MQTT, AMQP e todos os outros protocolos recebem o compositor e as amostras de CLI copiáveis, e o painel diz isso na própria página: o Blume não simula conectividade com broker a partir de uma aba do navegador.

`asyncapi.playground` espelha `openapi.playground` — ligado por padrão com o renderizador nativo, e `false` é todo o interruptor de desligamento:

```ts blume.config.ts lineNumbers
asyncapi: {
  enabled: true,
  spec: "./asyncapi.yaml",
  playground: false,
}
```

:::note
`playground.proxy` não se aplica a operações de evento. Ele encaminha requisições HTTP, e uma conexão WebSocket vai direto do navegador para o servidor nomeado na URL, então não há nada na frente de que um proxy possa ficar.
:::

O compositor de eventos não coleta credenciais de broker. A seção **Authorization** de cada página de operação documenta o que o broker espera, e uma conexão WebSocket carrega apenas o que já está na URL. Nada é persistido para operações de evento.
