> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mka1.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Guia de primeiros passos da plataforma MKA1

> De um link de convite do cluster até criar aplicações com o SDK MKA1. Aceite seu convite, configure sua organização, gere uma chave de API e faça sua primeira requisição.

<Note>
  **O QUE VOCÊ DEVE TER EM MÃOS**

  1. **Um link de convite do cluster** enviado a você pelo administrador do seu cluster. Ele torna você o proprietário de uma organização totalmente nova.
  2. **Este guia** tudo o que você precisa para ir desse link a uma integração funcional.
</Note>

**Links rápidos**

* [Referência da API](https://docs.mka1.com/api-reference/introduction)
* [SDK TypeScript no npm](https://www.npmjs.com/package/@meetkai/mka1)
* [SDK Python no PyPI](https://pypi.org/project/meetkai-mka1/)
* [SDK C# no NuGet](https://www.nuget.org/packages/MeetKai.MKA1/)
* [Instalação da CLI](https://docs.mka1.com/docs/cli/introduction)

## Bem-vindo ao MKA1

MKA1 é uma plataforma para criar aplicações de IA. Ela dá à sua equipe um único gateway para grandes modelos de linguagem, além dos blocos de construção de alto nível de que produtos reais precisam: agentes, conversas armazenadas, memória de longo prazo, recuperação de documentos (RAG), ferramentas e servidores MCP, prompts, habilidades, guardrails, fala e avaliações.

Você trabalha com o MKA1 por meio de duas superfícies que compartilham as mesmas contas, equipes e recursos:

* **O Console** - um painel web para criar e inspecionar tudo manualmente: executar prompts no Playground, salvar agentes, indexar arquivos, gerar chaves de API, gerenciar sua organização e equipes. O console fica no endereço do seu cluster (por exemplo platform.mka1.com).
* **A API e os SDKs** - as mesmas capacidades via HTTPS, chamadas do seu próprio código pelo SDK TypeScript, Python ou C#, pela CLI `mka1` ou por curl puro. É assim que sua aplicação conversa com o MKA1 em produção.

Este guia percorre todo o caminho em ordem. Os passos 1–7 levam você do link de convite até sua primeira requisição bem-sucedida; as seções seguintes percorrem cada bloco de construção com exemplos prontos para copiar e colar.

## Antes de começar

Você só precisa de duas coisas para começar, e já tem ambas:

1. **Um link de convite do cluster.** Seu administrador criou um convite no cluster e enviou o link para você. Abri-lo torna você o proprietário de uma nova organização dentro daquele cluster.
2. **Este guia.** Ele leva você do convite a uma integração funcional com o SDK.

Nada para instalar de antemão. O console roda no seu navegador, e você só instala um SDK quando estiver pronto para escrever código. O caminho abaixo leva cerca de 15 minutos:

<Note>
  **Configuração em 15 minutos**

  * **Passo 1** Aceite seu convite do cluster e crie sua organização.
  * **Passo 2** Oriente-se no console.
  * **Passo 3** Convide colegas e crie uma equipe (as chaves de API vivem nas equipes).
  * **Passo 4** Crie uma chave de API.
  * **Passo 5** Instale um SDK.
  * **Passo 6** Autentique suas requisições.
  * **Passo 7** Faça sua primeira requisição.
</Note>

## Passo 1 · Aceite seu convite do cluster

Abra o link de convite do cluster que seu administrador enviou. Ele carrega um token de uso único e leva você à página **Set up your organization**. Um convite de cluster é um **convite de proprietário** - aceitá-lo cria uma nova organização e define você como o proprietário.

### Faça isto

1. **Abra o link de convite.** A página valida o token e mostra um selo de *Owner invite* (e uma data de expiração, se houver). Se disser que o convite está indisponível, o token de convite expirou ou foi revogado. Peça um link novo ao seu administrador.
2. **Nomeie sua organização.** Digite um nome como Acme Inc. Um slug de URL do workspace é gerado para você (p. ex. acme-inc); expanda **Customize** se quiser editá-lo. Apenas letras minúsculas, números e hífens.
3. **Escolha como entrar.** Crie uma conta com e-mail e senha, ou continue com o Google. Se o convite estava vinculado ao seu endereço de e-mail, esse endereço aparece pré-preenchido e travado.
4. **Verifique seu e-mail.** Se você se cadastrou com senha, o MKA1 envia um e-mail de verificação. Clique no link para confirmar; você então cai direto na sua nova organização.
5. **Você está dentro.** Você chega ao console como **proprietário** da sua organização, pronto para convidar colegas e criar chaves.

<Note>
  **Agora você é o proprietário da organização**

  O proprietário tem controle total. Uso, membros, equipes e configurações. Todos os demais que você trouxer serão administradores ou membros (coberto no Passo 3). Se você já estava conectado ao MKA1 com um e-mail diferente do convite, saia primeiro: os convites são vinculados a um endereço específico.
</Note>

## Passo 2 · Conheça o console

Reserve um minuto para se orientar. A barra lateral esquerda agrupa cada superfície em **Access**, **LLM**, **Agents** e **Admin**. Veja para que serve cada seção. Você usará várias delas nos próximos passos.

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/console-organizations.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=18e5508504a8d674c2e24b795fbf4d14" alt="Configurações de organizações no console do MKA1" width="1999" height="1173" data-path="images/platform-getting-started/console-organizations.png" />

### Access

| Seção                | O que você faz lá                                                                |
| :------------------- | :------------------------------------------------------------------------------- |
| **API Keys**         | Crie e gerencie as chaves de autenticação que seu código usa (Passo 4).          |
| **Organizations**    | Gerencie membros, papéis, equipes e convites pendentes.                          |
| **Teams**            | Crie equipes e gerencie seus membros. Cada chave de API é limitada a uma equipe. |
| **Service Accounts** | Crie identidades não humanas para produção e vincule-as a equipes.               |

### LLM

| Seção              | O que você faz lá                                                                                                                                                   |
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Playground**     | Converse com modelos interativamente. Transmita respostas em tempo real. Configure ferramentas, habilidades e guardrails, com um painel de configurações avançadas. |
| **Models**         | Explore os modelos disponíveis pelo gateway, agrupados por modalidade, com detalhes de registro para administradores.                                               |
| **Responses**      | Crie respostas individuais e inspecione histórico armazenado, saída, chamadas de ferramentas e uso de tokens.                                                       |
| **Evals**          | Monte suítes de avaliação e lance execuções duráveis para medir e comparar a qualidade dos modelos.                                                                 |
| **Conversations**  | Crie e inspecione o estado de conversas armazenadas, pesquisável por metadados.                                                                                     |
| **Text to speech** | Sintetize fala a partir de texto e inspecione o histórico de geração.                                                                                               |
| **Speech to text** | Transcreva áudio para texto e inspecione o histórico de transcrições.                                                                                               |
| **Prompts**        | Crie, versione e reverta modelos de prompt reutilizáveis com `{{variables}}`.                                                                                       |
| **Guardrails**     | Configure políticas de palavras banidas, injeção de prompt e vazamento, e depois teste-as.                                                                          |
| **Files**          | Envie, inspecione e exclua arquivos usados por fluxos de trabalho LLM.                                                                                              |
| **Vector Stores**  | Crie lojas, anexe arquivos e pesquise trechos de documentos indexados para recuperação (RAG).                                                                       |
| **Feedback**       | Registre e atualize feedback humano sobre a saída do modelo; consulte registros ou exporte um snapshot em parquet.                                                  |
| **Skills**         | Envie, versione e gerencie habilidades reutilizáveis, cada uma empacotada atrás de um manifesto SKILL.md.                                                           |
| **MCP Servers**    | Registre definições de servidores MCP que agentes salvos podem anexar como ferramentas; os segredos ficam em Credentials.                                           |
| **Credentials**    | Armazene os segredos de que seus servidores MCP e integrações precisam, separados de suas definições.                                                               |

### Agents

| Seção             | O que você faz lá                                                                                                 |
| :---------------- | :---------------------------------------------------------------------------------------------------------------- |
| **Quickstart**    | Coloque um agente salvo no ar rapidamente - escolha um modelo, escreva instruções, anexe ferramentas e execute-o. |
| **Agents**        | Crie e execute agentes salvos que agrupam um modelo, instruções, ferramentas e metadados.                         |
| **Sessions**      | Rastreie e depure execuções de agentes. Reproduza a transcrição e percorra os eventos brutos.                     |
| **Memory Stores** | Explore as memórias em markdown que os agentes leem e escrevem entre execuções.                                   |

### Admin

| Seção              | O que você faz lá                                                                                                                                                                                |
| :----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Audit**          | Revise requisições de auditoria do gateway, monte casos e exporte respostas (administradores do cluster veem todas as organizações; administradores de organização veem a atividade da sua org). |
| **Alerts**         | Registre endpoints de webhook que disparam quando respostas falham, com escopo de cluster, organização ou equipe.                                                                                |
| **Model Registry** | Adicione e configure os modelos personalizados disponíveis no registro da sua organização.                                                                                                       |
| **Pricing**        | Mantenha o livro de preços de modelos: moeda do cluster, preços por modelo e substituições por organização (apenas administradores do cluster).                                                  |
| **Budgets**        | Crie orçamentos de gasto da org com limiares de alerta/bloqueio e status de gasto ao vivo (orçamentos de chaves de API são geridos pelo administrador do cluster).                               |
| **Usage**          | Revise o uso de tokens, requisições e armazenamento da org e equipe ativas.                                                                                                                      |
| **Fine-tuning**    | Lance e monitore execuções de fine-tuning e checkpoints (em breve).                                                                                                                              |
| **Serving**        | Implante modelos no cluster: implantações com escalonamento e reversão, registros de modelos, imagens, trabalhos de fine-tuning, aceleradores e segredos (administradores).                      |

## Passo 3 · Convide sua equipe e organize o acesso

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/team-detail.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=ee9ab4318584cf0bb683d6eefda81963" alt="Página de detalhe de equipe em Access → Teams" width="1999" height="1173" data-path="images/platform-getting-started/team-detail.png" />

O acesso ao MKA1 é organizado como uma hierarquia simples: **organização → equipes → membros**, com **papéis** controlando o que cada pessoa pode fazer e **contas de serviço** representando os chamadores não humanos.

### A organização e seu proprietário

Quando você aceita o convite do cluster, torna-se o **proprietário** da sua organização. O proprietário tem controle total: métricas de uso, membros, equipes e configurações. Todos os demais que você trouxer são **administradores** ou **membros**:

| Papel             | O que podem fazer                                                |
| :---------------- | :--------------------------------------------------------------- |
| **Proprietário**  | Controle total da organização - uso, membros e configurações.    |
| **Administrador** | Gerencia membros, equipes e chaves de API em toda a organização. |
| **Membro**        | Acessa os modelos, arquivos e chaves de API da sua equipe.       |

### Equipes

Dentro de uma organização você cria **equipes**, e os membros pertencem a uma ou mais delas. As equipes são onde o trabalho e o acesso realmente vivem: **chaves de API, agentes e outros recursos são limitados a uma única equipe.** Uma chave gerada em uma equipe concede acesso apenas aos recursos daquela equipe. Remover alguém (ou uma conta de serviço) de uma equipe revoga o acesso que vinha com ela, e as chaves ligadas àquela equipe param de funcionar. Isso torna as equipes a fronteira natural para separar projetos, ambientes ou unidades de negócio. Gerencie-as em **Access → Teams**, onde você pode criar uma equipe e gerenciar sua lista simples de membros.

### Convidando colegas

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/invite-people.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=6c07315e06afc45e5681cfdfef0e907b" alt="Diálogo de convidar pessoas com seleção de papel e equipes" width="1999" height="1173" data-path="images/platform-getting-started/invite-people.png" />

Para adicionar uma pessoa, envie a ela um **convite de organização** por e-mail. Você pode fazer isso navegando até **Access → Organizations** e clicando em **Invite people** no canto superior direito. Compartilhe o link gerado que abre a página **Accept invite**, que mostra a organização, quem convidou, o papel que a pessoa receberá e quando o convite expira.

O que a pessoa faz para aceitar depende do seu estado:

* **Ainda sem conta** (Este é o cenário mais provável) - ela se cadastra (e-mail/senha ou Google) com o e-mail convidado, verifica-o e volta ao convite para concluir a entrada.
* **Já conectada com o e-mail convidado** - um clique em **Accept & join** a adiciona à organização.
* **Conectada com um e-mail diferente** - ela é orientada a trocar primeiro para a conta convidada, já que os convites são vinculados a um endereço específico.

Convites podem expirar ou ser revogados, então envie um link novo se alguém relatar um link morto.

### Contas de serviço para produção

Para sistemas de produção, executores de CI, serviços de backend e trabalhos agendados, use uma **conta de serviço** em vez das credenciais de uma pessoa. Uma conta de serviço é uma identidade de máquina não humana que você vincula a uma ou mais equipes e para a qual gera chaves de API. Você pode criar uma navegando até **Access → Service accounts** e clicando em **New service account** no canto superior direito. Como as chaves herdam o escopo da equipe, desvincular uma conta de serviço de uma equipe (ou excluí-la) interrompe imediatamente todas as chaves geradas para ela naquela equipe, dando a você um interruptor de desligamento limpo para credenciais de produção.

## Passo 4 · Crie uma chave de API

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/create-api-key.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=31359eac6502261378a6f4fac8acc238" alt="Formulário de nova chave de API com etapas de identidade, vinculação de escopo e permissões" width="1999" height="1173" data-path="images/platform-getting-started/create-api-key.png" />

Uma chave de API é a credencial que seu código envia em cada requisição. No console, abra **Access → API Keys** e clique em **Create API key**. O formulário percorre quatro etapas.

### 1 · Identidade

Nomeie a chave (p. ex. Production gateway) e escolha o principal como o qual ela age: **My user** (usa seu papel na org e a equipe selecionada) ou uma **Service account** (uma identidade não humana dedicada. Contas de serviço são recomendadas para casos de uso em produção).

### 2 · Vinculação de escopo

Escolha a **organização** e a **equipe** às quais a chave pertence. Uma chave só pode ver recursos dentro daquela única equipe naquela única org — então escolha a equipe cujos modelos, arquivos e agentes esta chave deve alcançar. (Se você ainda não tem equipe, crie uma primeiro em **Access → Teams**; as chaves precisam ser limitadas a uma equipe.)

### 3 · Permissões (scopes)

Escolha quais recursos a chave pode **ler** e **escrever**. Os scopes são verificados em cada requisição. Use um preset para avançar rápido e depois ajuste:

* **Standard** - os scopes cotidianos de leitura/escrita para criar apps (respostas, conversas, arquivos, lojas vetoriais, prompts, agentes e mais).
* **Read-only** - todos os scopes `read:` e nada mais.
* **All** - todos os scopes, incluindo os exclusivos de administrador. Disponível apenas para proprietários e administradores da org.

Alguns scopes são **exclusivos de administrador** (fine-tuning, registro de modelos, guardrails, busca, lotes, sandbox, autorização refinada) e aparecem apenas se você for proprietário ou administrador. Conceda o conjunto mais restrito de que a chave realmente precisa.

### 4 · Limite de taxa (opcional)

Opcionalmente limite a chave a um número máximo de requisições por minuto, hora ou dia. O gateway aplica o limite e retorna `429 Too Many Requests` antes de a requisição chegar a um modelo, então chamadas acima do limite não custam nada.

<Warning>
  **Copie o segredo agora — ele é mostrado apenas uma vez**

  Quando você clica em **Create key**, o segredo completo é revelado uma **única vez**. Copie-o imediatamente e guarde-o em um lugar seguro (um gerenciador de segredos ou seu .env). Se você o perder, não poderá vê-lo novamente. Regenere a chave para obter um novo segredo. Trate-o como uma senha: nunca o envie para o controle de versão nem o exponha em código de navegador.
</Warning>

## Passo 5 · Instale um SDK

O MKA1 oferece SDKs para TypeScript, Python e C#, além de uma CLI `mka1` independente. Cada cliente se autentica com sua chave de API como token Bearer e aponta para o gateway da API. O gateway hospedado padrão é `https://apigw.mka1.com`.

<Note>
  **Clusters privados**

  Em uma implantação privada, substitua `https://apigw.mka1.com` pelo host do gateway do seu próprio cluster em tudo abaixo. Passe-o como a opção `serverURL` / `server_url` / `serverUrl` do SDK, ou configure-o uma vez para a CLI. Seu administrador pode informar a URL do gateway (é a contraparte de API do endereço do seu console).
</Note>

### TypeScript - @meetkai/mka1

O SDK TypeScript é instalado a partir do registro de pacotes npm:

```bash theme={null}
npm add @meetkai/mka1
```

```ts theme={null}
import { SDK } from '@meetkai/mka1';

const mka1 = new SDK({ bearerAuth: 'Bearer YOUR_API_KEY' });
```

### Python - [meetkai-mka1](https://pypi.org/project/meetkai-mka1/)

Requer Python 3.10 ou mais recente:

```bash theme={null}
pip install meetkai-mka1
```

```python theme={null}
from meetkai_mka1 import SDK

sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")
```

### C# - [MeetKai.MKA1](https://www.nuget.org/packages/MeetKai.MKA1/)

```csharp theme={null}
using MeetKai.MKA1;

var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");
```

### CLI - [mka1](https://docs.mka1.com/docs/cli/introduction)

Binários pré-compilados são servidos em downloads.mka1.com. No macOS (Apple silicon):

```bash theme={null}
curl -fsSL https://downloads.mka1.com/darwin/mka1_darwin_arm64-latest.tar.gz \
  | tar -xz -C /usr/local/bin mka1
mka1 version
```

Troque arm64 por x86\_64 no Intel; pacotes .deb/.rpm e um .zip para Windows estão vinculados no [guia da CLI](https://docs.mka1.com/docs/cli/introduction). Depois configure sua chave e execute qualquer comando:

```bash theme={null}
export MKA1_BEARER_AUTH="Bearer YOUR_API_KEY"
mka1 llm models list
```

Para uma configuração persistente que armazena segredos no chaveiro do seu SO, veja [autenticar a CLI](https://docs.mka1.com/docs/cli/authentication).

## Passo 6 · Autentique suas requisições

Cada requisição carrega sua chave de API como token bearer no cabeçalho `Authorization`. Para apps multiusuário do lado do servidor você também envia `X-On-Behalf-Of` para identificar para qual dos *seus* usuários finais a requisição é.

```http theme={null}
Authorization: Bearer YOUR_API_KEY
```

### Quando enviar X-On-Behalf-Of

Defina `X-On-Behalf-Of` com um **identificador estável do seu próprio sistema** (p. ex. `user_123`) sempre que seu servidor estiver agindo por um usuário final específico. Isso mantém as requisições, arquivos, memória e uso desse usuário corretamente atribuídos. Use um ID que não muda. Nunca use um e-mail ou nome de exibição.

* **Somente Authorization** - seu próprio fluxo de trabalho de backend, não vinculado a nenhum usuário final.
* **Authorization + X-On-Behalf-Of** - seu servidor agindo por um dos seus usuários finais; o uso e os recursos ficam associados a ele.

<CodeGroup>
  ```ts TypeScript theme={null}
  import type { ResponseObject } from '@meetkai/mka1/models/components';

  const result = await mka1.llm.responses.create({
    xOnBehalfOf: 'user_123',
    responsesCreateRequest: {
      model: 'meetkai:functionary-pt',
      input: 'Resuma este ticket de suporte.',
    },
  }) as ResponseObject;
  console.log(result.outputText);
  ```

  ```python Python theme={null}
  response = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      input="Resuma este ticket de suporte.",
      x_on_behalf_of="user_123",
  )
  ```
</CodeGroup>

### Emita tokens de curta duração (opcional)

Quando um serviço downstream ou um cliente de navegador precisa chamar o MKA1 sem possuir sua chave de API, troque a chave por um JWT de curta duração via `POST /api/v1/authentication/api-keys/exchange-token`, e então use esse JWT como token bearer. Veja o [guia de autenticação](https://docs.mka1.com/docs/authentication) e o [aprofundamento](https://docs.mka1.com/docs/authentication-deep-dive).

<CodeGroup>
  ```bash bash theme={null}
  curl -X POST https://apigw.mka1.com/api/v1/authentication/api-keys/exchange-token \
    --header "Authorization: Bearer YOUR_API_KEY" \
    --header 'Content-Type: application/json' \
    --data '{ "audience": "https://your-app.example.com", "externalUserId": "user_123" }'
  # → { "token": "<jwt>" } — depois envie Authorization: Bearer <jwt>
  ```

  ```ts TypeScript theme={null}
  const jwt = await mka1.auth.apiKeys.exchangeToken({
    requestBody: {
      audience: 'https://your-app.example.com',
      externalUserId: 'user_123',
    },
  });

  // jwt.token é o JWT de curta duração — use-o como bearer
  const asEndUser = new SDK({ bearerAuth: `Bearer ${jwt.token}` });
  ```

  ```python Python theme={null}
  jwt = sdk.auth.api_keys.exchange_token(body={
      "audience": "https://your-app.example.com",
      "external_user_id": "user_123",
  })

  # jwt.token é o JWT de curta duração — use-o como bearer
  as_end_user = SDK(bearer_auth=f"Bearer {jwt.token}")
  ```
</CodeGroup>

## Passo 7 · Faça sua primeira requisição

Com uma chave em mãos, gere sua primeira resposta. Usar `model: 'auto'` deixa o gateway escolher o modelo certo para a requisição.

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/response-detail.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=b7f8a1be0bd0a932fd79c8570778417c" alt="Uma resposta concluída no console com entrada, raciocínio e saída" width="1999" height="1173" data-path="images/platform-getting-started/response-detail.png" />

<CodeGroup>
  ```bash CLI theme={null}
  mka1 llm responses create \
    --model meetkai:functionary-pt \
    --input '"Qual é a capital da França?"' \
    -H 'X-On-Behalf-Of: <end-user-id>'
  ```

  ```ts TypeScript theme={null}
  import { SDK } from '@meetkai/mka1';
  import type { ResponseObject } from '@meetkai/mka1/models/components';

  const mka1 = new SDK({ bearerAuth: 'Bearer YOUR_API_KEY' });

  const result = await mka1.llm.responses.create({
    responsesCreateRequest: {
      model: 'meetkai:functionary-pt',
      input: 'Qual é a capital da França?',
    },
  }) as ResponseObject;
  console.log(result.outputText);
  ```

  ```python Python theme={null}
  from meetkai_mka1 import SDK

  sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

  res = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      input="Qual é a capital da França?",
  )
  ```

  ```bash curl theme={null}
  curl https://apigw.mka1.com/api/v1/llm/responses \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer YOUR_API_KEY' \
    --data '{ "model": "meetkai:functionary-pt", "input": "Qual é a capital da França?" }'
  ```
</CodeGroup>

Esse é o caminho completo a partir do zero. Você tem uma organização, uma equipe, uma chave de API, um SDK e uma requisição funcionando. O restante deste guia percorre os blocos de construção que você montará em aplicações reais.

## Construa com a plataforma

Tudo abaixo pode ser chamado com a chave de API que você acabou de criar. Cada seção se baseia nos guias oficiais em docs.mka1.com. Siga os links incorporados para a referência completa.

## Gerar respostas (a chamada principal)

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/playground-advanced-settings.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=4508ba4961de54cf286ead2820124a69" alt="Playground com o painel de configurações avançadas aberto" width="1999" height="1173" data-path="images/platform-getting-started/playground-advanced-settings.png" />

O recurso Responses é como você gera texto com o MKA1. Passe uma string simples em `input` para um prompt de turno único; o resultado inclui o texto gerado em `output_text`. Use `auto_routing: true` para deixar o gateway escolher o modelo certo por você.

### Chamada básica

<CodeGroup>
  ```ts TypeScript theme={null}
  import { SDK } from '@meetkai/mka1';

  const mka1 = new SDK({
    bearerAuth: `Bearer ${YOUR_API_KEY}`,
  });

  const result = await mka1.llm.responses.create({
    xOnBehalfOf: '<end-user-id>',
    responsesCreateRequest: {
      model: 'meetkai:functionary-pt',
      input: 'Escreva um resumo de uma frase da API do MKA1.',
    },
  });
  ```

  ```python Python theme={null}
  from meetkai_mka1 import SDK

  sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

  res = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      input="Escreva um resumo de uma frase da API do MKA1.",
      http_headers={"X-On-Behalf-Of": "<end-user-id>"},
  )
  ```
</CodeGroup>

Passe `X-On-Behalf-Of` quando estiver agindo por um usuário final; omita-o caso contrário.

### O que auto\_routing faz

`auto_routing` é um sinalizador de requisição opcional, separado do alias de modelo `auto`. Quando você define `auto_routing: true`, o gateway pontua a complexidade da requisição e a roteia para o melhor irmão **quantizado**, **MoE** ou **denso** *dentro da família de modelos que você solicitou*. Ele nunca troca para um modelo não relacionado, e recorre ao modelo que você pediu se aquela família não tiver um irmão compatível.

A pontuação é aditiva. Ela sobe com o comprimento do prompt, muitas ferramentas ou ferramentas de alta agência (p. ex. `code_interpreter`, `mcp`), `tool_choice: 'required'`, saída estruturada, um `max_output_tokens` grande, contexto de múltiplos turnos e sinais de raciocínio complexo no texto (debug, refactor, plan, incident, code); ela desce com prompts curtos e tarefas simples reconhecidas (traduzir, resumir, classificar, extrair). O total escolhe o nível. Pontuações mais altas roteiam para `dense`, médias para `moe`, baixas para `quantized`. Um `reasoning.effort` correspondente é definido (de `minimal` até `xhigh`) a menos que você mesmo tenha definido o esforço. Assim, um curto "resuma isto" é roteado para `quantized` com esforço `minimal`, enquanto um longo relato de incidente é roteado para `dense` com esforço `high` (ou `xhigh`).

Sempre que o roteamento é executado, os metadados da resposta registram `routed_model` - a variante realmente usada. Adicione `auto_routing_debug: true` para obter também um campo de metadados `auto_routing_debug`: uma string JSON compacta com o modelo solicitado e o roteado, o nível escolhido, o esforço de raciocínio, a pontuação e as razões por trás da decisão. Ele é registrado mesmo quando nenhuma variante irmã está disponível, então é útil para validar o comportamento do rollout. Deixe este campo desligado para o tráfego normal de produção.

### Transmita texto conforme ele é gerado

Defina `stream: true` para receber eventos enviados pelo servidor em vez de esperar a resposta completa. Use isso para renderizar a saída parcial conforme ela chega.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { CreateAcceptEnum } from '@meetkai/mka1/sdk/responses';
  import { EventStream } from '@meetkai/mka1/lib/event-streams';

  const stream = await mka1.llm.responses.create({
    responsesCreateRequest: {
      model: 'meetkai:functionary-pt',
      input: 'Escreva três itens de notas de versão para nossa atualização de docs.',
      stream: true,
    },
  }, { acceptHeaderOverride: CreateAcceptEnum.textEventStream });

  if (stream instanceof EventStream) {
    for await (const event of stream) {
      if (event.data.type === 'response.output_text.delta') {
        process.stdout.write(event.data.delta);
      }
    }
  }
  ```

  ```python Python theme={null}
  stream = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      input="Escreva três itens de notas de versão para nossa atualização de docs.",
      stream=True,
  )

  for event in stream:
      if event.data.type == "response.output_text.delta":
          print(event.data.delta, end="", flush=True)
  ```
</CodeGroup>

### Entrada multimodal (imagem + texto)

A API de Responses aceita texto, imagens, áudio e arquivos em uma única requisição. Use um array `input` estruturado de itens de mensagem, onde `content` é um array que mistura `input_text` e `input_image` (imagem via URL, URI de dados base64 ou um `file_id` enviado).

<CodeGroup>
  ```ts TypeScript theme={null}
  const result = await mka1.llm.responses.create({
    xOnBehalfOf: '<end-user-id>',
    responsesCreateRequest: {
      model: 'openai:gpt-4.1', // com visão — 'auto' descarta imagens hoje
      input: [
        {
          type: 'message',
          role: 'user',
          content: [
            { type: 'input_text', text: 'Descreva o que você vê nesta imagem.' },
            {
              type: 'input_image',
              imageUrl: 'https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg',
            },
          ],
        },
      ],
    },
  });
  ```

  ```python Python theme={null}
  res = sdk.llm.responses.create(
      model="openai:gpt-4.1",  # com visão — 'auto' descarta imagens hoje
      input=[
          {
              "type": "message",
              "role": "user",
              "content": [
                  {"type": "input_text", "text": "Descreva o que você vê nesta imagem."},
                  {
                      "type": "input_image",
                      "image_url": "https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg",
                  },
              ],
          },
      ],
      x_on_behalf_of="<end-user-id>",
  )
  ```
</CodeGroup>

### Respostas em segundo plano

Para trabalho de longa duração, defina `background: true` (com `stream: false`) para obter imediatamente uma resposta enfileirada, e depois recupere o resultado fazendo polling com `mka1.llm.responses.get(...)` ou por streaming. Veja o guia de [respostas em segundo plano](https://docs.mka1.com/docs/background-responses).

<CodeGroup>
  ```ts TypeScript theme={null}
  import type { ResponseObject } from '@meetkai/mka1/models/components';

  const queued = await mka1.llm.responses.create({
    responsesCreateRequest: {
      model: 'meetkai:functionary-pt',
      input: 'Escreva uma história do fax em duas frases.',
      background: true,
      stream: false,
    },
  }) as ResponseObject;

  // queued.status === 'queued'

  let response = queued;
  while (response.status === 'queued' || response.status === 'in_progress') {
    await new Promise((r) => setTimeout(r, 2000));
    response = await mka1.llm.responses.get({ responseId: queued.id }) as ResponseObject;
  }
  console.log(response.outputText);
  ```

  ```python Python theme={null}
  import time

  queued = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      input="Escreva uma história do fax em duas frases.",
      background=True,
      stream=False,
  )  # queued.status == "queued"

  response = queued
  while response.status in ("queued", "in_progress"):
      time.sleep(2)
      response = sdk.llm.responses.get(response_id=queued.id)

  print(response.output_text)
  ```
</CodeGroup>

#### Webhooks em vez de polling

Em vez de fazer polling, passe `webhook_url` (e opcionalmente `webhook_secret`) ao criar uma resposta em segundo plano. O gateway envia por POST cada mudança de status ao seu endpoint — `response.queued`, `response.in_progress`, `response.completed`, `response.failed`, `response.incomplete`, `response.cancelled` — como `{ event, resource_id, created_at, data }`, onde `data` é o objeto de evento completo.

Com um segredo definido, cada entrega carrega `X-Webhook-Signature: sha256=<hex>`, um HMAC-SHA256 do corpo JSON bruto — verifique-o antes de confiar no payload. A entrega nunca bloqueia a resposta: três tentativas com backoff exponencial e um tempo limite de 10 segundos. O endpoint precisa ser acessível publicamente — endereços privados e localhost são rejeitados. O gateway exige que `webhook_secret` tenha pelo menos 16 caracteres.

<CodeGroup>
  ```ts TypeScript theme={null}
  const queued = await mka1.llm.responses.create({
    responsesCreateRequest: {
      model: 'meetkai:functionary-pt',
      input: 'Resuma este relatório de 80 páginas…',
      background: true,
      stream: false,
      webhookUrl: 'https://your-app.example.com/hooks/mka1',
      webhookSecret: process.env.MKA1_WEBHOOK_SECRET,
    },
  }) as ResponseObject;
  ```

  ```python Python theme={null}
  import os

  queued = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      input="Resuma este relatório de 80 páginas…",
      background=True,
      stream=False,
      webhook_url="https://your-app.example.com/hooks/mka1",
      webhook_secret=os.environ["MKA1_WEBHOOK_SECRET"],
  )
  ```
</CodeGroup>

Para o seu lado receptor:

```ts theme={null}
import crypto from 'node:crypto';

// No seu handler de webhook — verifique X-Webhook-Signature contra o corpo bruto da requisição
function isValidSignature(rawBody: string, signatureHeader: string, secret: string) {
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
}
```

## Conversas e memória

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/conversation-detail.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=78e6fd0f03347ab78f5e57bf0ac76804" alt="Detalhe de conversa com itens e metadados" width="1999" height="1173" data-path="images/platform-getting-started/conversation-detail.png" />

O MKA1 oferece duas formas complementares de manter o contexto entre turnos: **conversas com estado** (histórico mantido para uma sessão, no servidor) e a **loja de memória de longo prazo** (a ferramenta history, persistente entre sessões e com escopo por usuário final).

### Conversas com estado

Uma conversa é um contêiner do lado do servidor que o gateway usa para manter o estado entre requisições de Responses, para que você nunca reenvie o histórico completo. Crie uma e depois passe seu ID em cada resposta de acompanhamento.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { SDK } from '@meetkai/mka1';

  const mka1 = new SDK({ bearerAuth: `Bearer ${YOUR_API_KEY}` });

  // 1. Crie uma conversa (metadados opcionais para seu próprio roteamento)
  const conv = await mka1.llm.conversations.create({
    xOnBehalfOf: '<end-user-id>',
    createConversationRequest: {
      metadata: { session_id: 'web-42', channel: 'support' },
    },
  });

  // 2. (Opcional) escreva o histórico explicitamente antes de chamar Responses
  await mka1.llm.conversations.createItems({
    conversationId: conv.id,
    xOnBehalfOf: '<end-user-id>',
    createItemsRequest: {
      items: [
        { type: 'message', role: 'user', content: 'Resuma o ticket de suporte mais recente.' },
      ],
    },
  });

  // 3. Continue o fluxo — anexe a conversa para que o modelo tenha histórico
  const result = await mka1.llm.responses.create({
    responsesCreateRequest: {
      model: 'meetkai:functionary-pt',
      conversation: conv.id,
      input: 'Transforme esse resumo em uma resposta pronta para o cliente.',
    },
  });
  ```

  ```python Python theme={null}
  # 1. Crie uma conversa (metadados opcionais para seu próprio roteamento)
  conv = sdk.llm.conversations.create(
      metadata={"session_id": "web-42", "channel": "support"},
      x_on_behalf_of="<end-user-id>",
  )

  # 2. (Opcional) escreva o histórico explicitamente antes de chamar Responses
  sdk.llm.conversations.create_items(
      conversation_id=conv.id,
      items=[
          {"type": "message", "role": "user", "content": "Resuma o ticket de suporte mais recente."},
      ],
      x_on_behalf_of="<end-user-id>",
  )

  # 3. Continue o fluxo — anexe a conversa para que o modelo tenha histórico
  result = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      conversation=conv.id,
      input="Transforme esse resumo em uma resposta pronta para o cliente.",
  )
  ```
</CodeGroup>

Passe `conversation` em cada requisição; o gateway mantém a thread por você. Use uma conversa quando quiser um contêiner reutilizável e inspecionável para muitos turnos e a capacidade de listar, buscar ou excluir itens depois. Use `previous_response_id` em vez disso quando só precisar bifurcar a partir de uma única resposta anterior.

### Loja de memória de longo prazo

A ferramenta history dá ao modelo memória que persiste **entre** sessões. Adicione `{ type: 'history' }` a `tools` e defina `store: true`; cada par requisição/resposta é indexado em segundo plano e pesquisado semanticamente (embeddings vetoriais) quando o modelo decide que precisa lembrar de algo. A memória é isolada por usuário final via o cabeçalho `X-On-Behalf-Of`.

<CodeGroup>
  ```ts TypeScript theme={null}
  // Sessão 1: armazene um fato
  await mka1.llm.responses.create({
    xOnBehalfOf: 'user-123',
    responsesCreateRequest: {
      model: 'meetkai:functionary-pt',
      input: 'Lembre-se disto: minha cor favorita é azul.',
      tools: [{ type: 'history' }],
      store: true,
    },
  });

  // Sessão 2 (minutos ou dias depois — a indexação leva ~1–2 min): recupere-o
  const recalled = await mka1.llm.responses.create({
    xOnBehalfOf: 'user-123',
    responsesCreateRequest: {
      model: 'meetkai:functionary-pt',
      input: 'Qual é a minha cor favorita?',
      tools: [{ type: 'history' }],
      store: true,
    },
  });
  // → "Sua cor favorita é azul."
  ```

  ```python Python theme={null}
  # Sessão 1: armazene um fato
  sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      input="Lembre-se disto: minha cor favorita é azul.",
      tools=[{"type": "history"}],
      store=True,
      x_on_behalf_of="user-123",
  )

  # Sessão 2 (minutos ou dias depois — a indexação leva ~1–2 min): recupere-o
  recalled = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      input="Qual é a minha cor favorita?",
      tools=[{"type": "history"}],
      store=True,
      x_on_behalf_of="user-123",
  )
  ```
</CodeGroup>

**Regra prática:** as conversas mantêm uma sessão coerente; a ferramenta history carrega preferências, decisões e contexto adiante através de muitas sessões para o mesmo usuário.

## Arquivos, lojas vetoriais e recuperação (RAG)

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/vector-store-detail.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=737c6a62cbd16dac3298a304d647e60a" alt="Uma loja vetorial com arquivos anexados em indexação" width="1999" height="1173" data-path="images/platform-getting-started/vector-store-detail.png" />

O MKA1 divide a recuperação em dois recursos: **Files** guarda seus documentos enviados, e **Vector Stores** indexa esses arquivos para que você possa executar busca semântica sobre os trechos resultantes. Esse é o padrão para assistentes baseados em documentos e respostas fundamentadas. A indexação é automática. Você envia, anexa e pesquisa; o MKA1 cuida do fatiamento e dos embeddings.

Todos os trechos abaixo usam o SDK MKA1 de TypeScript ou Python. Inicialize o cliente uma vez:

<CodeGroup>
  ```ts TypeScript theme={null}
  import { SDK } from '@meetkai/mka1';

  const mka1 = new SDK({ bearerAuth: 'Bearer <mka1-api-key>' });
  ```

  ```python Python theme={null}
  from meetkai_mka1 import SDK

  sdk = SDK(bearer_auth="Bearer <mka1-api-key>")
  ```
</CodeGroup>

### 1. Envie um arquivo

Envie o documento uma vez. A resposta retorna um objeto de arquivo cujo `id` se parece com `file_1783478060914_iemq10dh5h` — passe-o para as lojas vetoriais no próximo passo.

<CodeGroup>
  ```ts TypeScript theme={null}
  const file = Bun.file('./support-manual.pdf');

  const result = await mka1.llm.files.upload({
    xOnBehalfOf: '<end-user-id>',
    requestBody: { file, purpose: 'assistants' },
  });
  // result.id → p. ex. file_1783478060914_iemq10dh5h
  ```

  ```python Python theme={null}
  with open("support-manual.pdf", "rb") as fh:
      result = sdk.llm.files.upload(
          file={"file_name": "support-manual.pdf", "content": fh.read()},
          purpose="assistants",
          x_on_behalf_of="<end-user-id>",
      )
  # result.id → p. ex. file_1783481291595_r19s7ueog7o
  ```
</CodeGroup>

### 2. Crie uma loja vetorial e anexe arquivos

Crie uma loja vetorial, passando um ou mais IDs de arquivos enviados em `fileIds`. A loja retorna um ID como `vs_1783478061269_mptf5b93t0q`. Os arquivos anexados são indexados automaticamente.

<CodeGroup>
  ```ts TypeScript theme={null}
  const vectorStore = await mka1.llm.vectorStores.create({
    xOnBehalfOf: '<end-user-id>',
    createVectorStoreRequest: {
      name: 'Base de conhecimento de suporte',
      description: 'Manuais de suporte e documentos da central de ajuda indexados',
      fileIds: [result.id],
      expiresAfter: { anchor: 'last_active_at', days: 30 },
    },
  });
  ```

  ```python Python theme={null}
  vector_store = sdk.llm.vector_stores.create(
      name="Base de conhecimento de suporte",
      description="Manuais de suporte e documentos da central de ajuda indexados",
      file_ids=[result.id],
      expires_after={"anchor": "last_active_at", "days": 30},
      x_on_behalf_of="<end-user-id>",
  )
  ```
</CodeGroup>

Para adicionar mais arquivos depois sem recriar a loja, use `createFile`:

<CodeGroup>
  ```ts TypeScript theme={null}
  const second = await mka1.llm.files.upload({
    xOnBehalfOf: '<end-user-id>',
    requestBody: { file: Bun.file('./help-center-faq.pdf'), purpose: 'assistants' },
  });

  const vsFile = await mka1.llm.vectorStores.createFile({
    vectorStoreId: vectorStore.id,
    xOnBehalfOf: '<end-user-id>',
    createVectorStoreFileRequest: {
      fileId: second.id,
      attributes: { category: 'faq', version: '2.0' },
    },
  });
  ```

  ```python Python theme={null}
  with open("help-center-faq.pdf", "rb") as fh:
      second = sdk.llm.files.upload(
          file={"file_name": "help-center-faq.pdf", "content": fh.read()},
          purpose="assistants",
          x_on_behalf_of="<end-user-id>",
      )

  vs_file = sdk.llm.vector_stores.create_file(
      vector_store_id=vector_store.id,
      file_id=second.id,
      attributes={"category": "faq", "version": "2.0"},
      x_on_behalf_of="<end-user-id>",
  )
  ```
</CodeGroup>

Um arquivo de loja vetorial pode reportar `status: "in_progress"` enquanto a indexação roda, então espere o processamento terminar antes de confiar nos resultados de busca.

### 3. Pesquise trechos relevantes na loja

Execute uma busca semântica para recuperar os trechos mais relevantes para a pergunta de um usuário. A resposta retorna correspondências classificadas com `file_id`, `filename`, dados de pontuação e o conteúdo do trecho. Alimente esse texto na lógica da sua própria aplicação ou em uma requisição de Responses.

<CodeGroup>
  ```ts TypeScript theme={null}
  const results = await mka1.llm.vectorStores.search({
    vectorStoreId: vectorStore.id,
    xOnBehalfOf: '<end-user-id>',
    searchVectorStoreRequest: {
      query: 'Como redefino minha senha?',
      maxNumResults: 5,
    },
  });
  ```

  ```python Python theme={null}
  results = sdk.llm.vector_stores.search(
      vector_store_id=vector_store.id,
      query="Como redefino minha senha?",
      max_num_results=5,
      x_on_behalf_of="<end-user-id>",
  )
  ```
</CodeGroup>

### Bônus: extração estruturada

Quando você precisa de JSON tipado de um documento em vez de trechos de texto livre, use o recurso Extract. Para trabalho pontual, chame `extract` com um JSON Schema inline — passado como string JSON — e o arquivo a ler. Para trabalhos repetidos, salve o esquema uma vez com `createSchema` (aqui o esquema é um objeto simples) e execute-o contra muitos arquivos com `extractWithSchema`, referenciando o id do esquema retornado em `data.id`. Nomeie um modelo explicitamente em cada chamada de extração. Uma resposta bem-sucedida retorna `success`, um objeto `data` com os campos extraídos e `metadata` sobre a execução.

<CodeGroup>
  ```ts TypeScript theme={null}
  const schema = {
    type: 'object',
    properties: {
      document_title: { type: 'string' },
      reset_link_expiry_minutes: { type: 'number' },
      support_email: { type: 'string' },
    },
    required: ['document_title'],
  };

  // Extração pontual — aqui o esquema é uma string JSON
  const res = await mka1.llm.extract.extract({
    requestBody: {
      model: 'openai:gpt-4.1', // 'auto' atualmente retorna 500 neste endpoint
      prompt: 'Extraia o título do documento, a expiração do link de redefinição e o e-mail de suporte.',
      schema: JSON.stringify(schema),
      file: Bun.file('./support-manual.txt'),
    },
  });
  // → { success, data: {…}, metadata: {…} }
  ```

  ```python Python theme={null}
  import json

  schema = {
      "type": "object",
      "properties": {
          "document_title": {"type": "string"},
          "reset_link_expiry_minutes": {"type": "number"},
          "support_email": {"type": "string"},
      },
      "required": ["document_title"],
  }

  # Extração pontual — aqui o esquema é uma string JSON
  with open("support-manual.txt", "rb") as fh:
      res = sdk.llm.extract.extract(
          model="openai:gpt-4.1",  # 'auto' atualmente retorna 500 neste endpoint
          prompt="Extraia o título do documento, a expiração do link de redefinição e o e-mail de suporte.",
          schema=json.dumps(schema),
          file={"file_name": "support-manual.txt", "content": fh.read()},
      )
  # res.success, res.data, res.metadata
  ```
</CodeGroup>

<CodeGroup>
  ```ts TypeScript theme={null}
  // Modelo reutilizável — aqui o esquema é um objeto; o id chega em data.id
  const created = await mka1.llm.extract.createSchema({
    extractionSchema: {
      name: 'support-manual',
      description: 'Extrair dados do manual de suporte',
      schema,
    },
  });

  const out = await mka1.llm.extract.extractWithSchema({
    schemaId: created.data.id,
    requestBody: {
      model: 'openai:gpt-4.1',
      prompt: 'Extraia os campos.',
      file: Bun.file('./support-manual.txt'),
    },
  });
  ```

  ```python Python theme={null}
  # Modelo reutilizável — aqui o esquema é um dict; o id chega em data.id
  created = sdk.llm.extract.create_schema(
      name="support-manual",
      description="Extrair dados do manual de suporte",
      schema=schema,
  )

  out = sdk.llm.extract.extract_with_schema(
      schema_id=created.data.id,
      model="openai:gpt-4.1",
      prompt="Extraia os campos.",
      file={"file_name": "support-manual.txt", "content": open("support-manual.txt", "rb").read()},
  )
  ```
</CodeGroup>

## Agentes, ferramentas e MCP

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/agent-run.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=9873202c75de301445f64edba6c99064" alt="Executando um agente salvo a partir do console" width="1999" height="1173" data-path="images/platform-getting-started/agent-run.png" />

Um **agente salvo** é um objeto de agente reutilizável que armazena seu próprio comportamento para que você não reconstrua uma requisição de Responses a cada vez. Cada agente persiste um modelo, instruções e uma configuração de ferramentas (`tools`, `tool_choice`, `parallel_tool_calls`, `max_tool_calls`, `text`, `reasoning`). Quando você o executa, o serviço combina sua entrada por execução com a configuração salva e a encaminha para a API de Responses através do mkllm-gateway. Cada execução persiste a entrada mais o resultado de Responses do upstream, então você também ganha histórico de execuções de graça. Os agentes recebem um id estável como `agt_...`.

### Crie um agente

Crie um agente uma vez com os SDKs MKA1 de Python, TypeScript ou C#, incluindo uma ferramenta integrada `web_search` para que as execuções possam trazer informação externa atual:

<CodeGroup>
  ```ts TypeScript theme={null}
  import { SDK } from '@meetkai/mka1';

  const mka1 = new SDK({ bearerAuth: 'Bearer YOUR_API_KEY' });

  const agent = await mka1.agents.createAgent({
    createAgentRequest: {
      name: 'release-research-agent',
      description: 'Busca informações atuais de versões antes de responder.',
      model: 'meetkai:functionary-pt',
      instructions: 'Use a busca na web quando a pergunta depender de informação externa atual.',
      tools: [{ type: 'web_search', searchContextSize: 'medium' }],
      metadata: { team: 'docs' },
    },
  });
  console.log(agent.id);
  ```

  ```python Python theme={null}
  from meetkai_mka1 import SDK

  sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

  agent = sdk.agents.create_agent(
      name="release-research-agent",
      description="Busca informações atuais de versões antes de responder.",
      model="meetkai:functionary-pt",
      instructions="Use a busca na web quando a pergunta depender de informação externa atual.",
      tools=[{"type": "web_search", "search_context_size": "medium"}],
      metadata={"team": "docs"},
  )

  print(agent.id)
  ```
</CodeGroup>

O array `tools` completo (como enviado via HTTPS) configura a ferramenta integrada:

```json theme={null}
"tools": [
  { "type": "web_search", "search_context_size": "medium" }
],
"tool_choice": "auto",
"parallel_tool_calls": true
```

### Execute um agente

Execute enviando apenas a entrada por execução. A execução persiste `status`, o `gateway_response` armazenado e `gateway_response_id` da chamada upstream. Se a execução usou `web_search`, o `gateway_response` persistido inclui as entradas de chamadas de ferramentas.

<CodeGroup>
  ```ts TypeScript theme={null}
  const run = await mka1.agentRuns.createAgentRun({
    agentId: agent.id,
    createAgentRunRequest: {
      input: 'Qual é a versão estável atual do Bun? Use a busca na web antes de responder.',
      metadata: { request_source: 'docs' },
    },
  });

  console.log(run.gatewayResponseId);
  console.log(run.status);
  ```

  ```python Python theme={null}
  run = sdk.agent_runs.create_agent_run(
      agent_id="agt_123",
      input="Qual é a versão estável atual do Bun? Use a busca na web antes de responder.",
      metadata={"request_source": "docs"},
  )

  print(run.gateway_response_id)
  print(run.status)
  ```
</CodeGroup>

Use `sdk.agents.list_agents(...)` / `sdk.agent_runs.list_agent_runs(agent_id=...)` para inspecionar agentes salvos e execuções anteriores.

<CodeGroup>
  ```ts TypeScript theme={null}
  const agents = await mka1.agents.listAgents({});
  const runs = await mka1.agentRuns.listAgentRuns({ agentId: agent.id });
  ```

  ```python Python theme={null}
  agents = sdk.agents.list_agents()
  runs = sdk.agent_runs.list_agent_runs(agent_id="agt_123")
  ```
</CodeGroup>

### Histórico de versões e reversão

Cada alteração confirmada em um agente salvo — criar, atualizar, reverter — acrescenta uma versão imutável, então o histórico de configuração de um agente é sempre inspecionável. Reverter não reescreve o histórico: acrescenta uma nova versão restaurada a partir da versão alvo.

<CodeGroup>
  ```ts TypeScript theme={null}
  // Atualize o agente — isto confirma a versão 2
  await mka1.agents.updateAgent({
    agentId: agent.id,
    updateAgentRequest: { instructions: 'Responda com detalhes exaustivos.' },
  });

  // Inspecione o histórico
  const versions = await mka1.agentVersions.listAgentVersions({ agentId: agent.id });
  // versions.data → [ { version: 2, isCurrent: true, … }, { version: 1, … } ]

  // Busque uma versão completa
  const v2 = await mka1.agentVersions.getAgentVersion({ agentId: agent.id, version: 2 });

  // Reverta para a v1 — acrescenta a v3 com restoredFromVersion: 1
  await mka1.agentVersions.rollbackAgentVersion({ agentId: agent.id, version: 1 });
  ```

  ```python Python theme={null}
  sdk.agents.update_agent(agent_id=agent.id, instructions="Responda com detalhes exaustivos.")

  versions = sdk.agent_versions.list_agent_versions(agent_id=agent.id)
  # versions.data → [AgentVersion(version=2, is_current=True, …), AgentVersion(version=1, …)]

  v2 = sdk.agent_versions.get_agent_version(agent_id=agent.id, version=2)

  sdk.agent_versions.rollback_agent_version(agent_id=agent.id, version=1)
  # o histórico agora é v3 (atual, restored_from_version=1), v2, v1
  ```
</CodeGroup>

### Anexe um servidor de ferramentas MCP

Além das ferramentas integradas, você pode deixar o modelo chamar ferramentas de um servidor MCP externo adicionando uma entrada `mcp` a `tools`. Defina `require_approval` como `"never"` para executar imediatamente, ou `"always"` para pausar e pedir aprovação do usuário final. Limite as ferramentas invocáveis com `allowed_tools`; passe credenciais upstream em `headers` (elas são mascaradas nas respostas armazenadas).

<CodeGroup>
  ```ts TypeScript theme={null}
  import type { ResponseObject } from '@meetkai/mka1/models/components';

  const response = await mka1.llm.responses.create({
    responsesCreateRequest: {
      model: 'meetkai:functionary-pt',
      instructions: 'Use as ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos.',
      input: 'Liste minha issue mais recente do Linear atribuída a mim.',
      tools: [
        {
          type: 'mcp',
          serverLabel: 'Linear MCP',
          serverUrl: 'https://mcp.linear.app/mcp',
          allowedTools: ['issues.list'],
          headers: { Authorization: `Bearer ${process.env.LINEAR_API_KEY}` },
          requireApproval: 'never',
        },
      ],
    },
  }) as ResponseObject;

  console.log(response.outputText);
  ```

  ```python Python theme={null}
  import os

  response = sdk.llm.responses.create(
      model="meetkai:functionary-pt",
      instructions="Use as ferramentas do Linear quando o usuário perguntar sobre tarefas, bugs ou projetos.",
      input="Liste minha issue mais recente do Linear atribuída a mim.",
      tools=[
          {
              "type": "mcp",
              "server_label": "Linear MCP",
              "server_url": "https://mcp.linear.app/mcp",
              "allowed_tools": ["issues.list"],
              "headers": {"Authorization": f"Bearer {os.environ['LINEAR_API_KEY']}"},
              "require_approval": "never",
          },
      ],
  )

  print(response.output_text)
  ```
</CodeGroup>

O modelo chama a ferramenta MCP permitida e retorna a mensagem final em uma única requisição. Com `require_approval: "always"`, crie a resposta em modo de segundo plano, faça polling e trate o item `mcp_approval_request` devolvendo um `mcp_approval_response`.

## Prompts, habilidades e guardrails

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/prompt-detail.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=f940c3c74c8bd740787abbe6f6dd8346" alt="Um modelo de prompt versionado no repositório de prompts" width="1999" height="1173" data-path="images/platform-getting-started/prompt-detail.png" />

O MKA1 separa o *quê* de uma chamada LLM (seus prompts), as *capacidades* que você agrupa para ela (habilidades) e a *governança* que mantém o uso seguro e responsável (guardrails, limite de taxa e auditoria).

### Repositório de prompts

A API de Prompts armazena, versiona e renderiza modelos de prompt de forma centralizada. Cada alteração de modelo cria uma versão imutável, então você tem um histórico completo de mudanças e pode reverter para qualquer versão anterior a qualquer momento. Uma reversão não é destrutiva e apenas troca a versão ativa. Os modelos usam marcadores `{{variable}}` que são renderizados no lado do servidor quando você recupera um prompt, permitindo reutilizar um modelo em vários contextos. Os prompts são isolados por chave de API.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { SDK } from '@meetkai/mka1';

  const mka1 = new SDK({ bearerAuth: `Bearer ${YOUR_API_KEY}` });

  const prompt = await mka1.llm.prompts.create({
    createPromptRequest: {
      name: 'greeting',
      template: 'Olá, {{name}}! Bem-vindo à {{company}}.',
    },
  });

  const rendered = await mka1.llm.prompts.get({
    id: prompt.id,
    variables: JSON.stringify({ name: 'Alice', company: 'Acme' }),
  });
  console.log(rendered.renderedTemplate); // "Olá, Alice! Bem-vindo à Acme."
  ```

  ```python Python theme={null}
  import json

  prompt = sdk.llm.prompts.create(
      name="greeting",
      template="Olá, {{name}}! Bem-vindo à {{company}}.",
  )

  rendered = sdk.llm.prompts.get(
      id=prompt.id,
      variables=json.dumps({"name": "Alice", "company": "Acme"}),
  )
  print(rendered.rendered_template)  # "Olá, Alice! Bem-vindo à Acme."
  ```
</CodeGroup>

### Habilidades

Habilidades são pacotes de capacidades reutilizáveis e versionados que você envia ao gateway. Cada habilidade empacota o comportamento de ferramentas atrás de um manifesto SKILL.md. O nome e a descrição da habilidade são lidos diretamente desse manifesto. Você pode enviar um único conjunto de arquivos ou um pacote completo, gerenciar versões (cada habilidade rastreia uma versão padrão e a mais recente) e revisar cada arquivo antes de criá-la. Gerencie as habilidades no painel em **Skills**, ou via a API de Skills.

### Guardrails, limite de taxa e auditoria de uso

Esses três recursos de governança mantêm o tráfego delegado e multiusuário controlado e responsável:

* **Limite de taxa** - Cada chave de API pode carregar uma cota sobre uma janela configurável — por minuto, hora ou dia. Quando uma chave excede seu limite, o gateway retorna `429 Too Many Requests` antes de a requisição chegar ao modelo, então nenhum token é consumido e nenhum uso é cobrado. Trate os 429 com novas tentativas de backoff exponencial.
* **Auditoria de uso** - Revise o uso de tokens, requisições e armazenamento por org e equipe em **Admin → Usage**, filtrável por usuário (membros da org). Para relatórios por usuário final, consulte a API de uso com seu filtro `external_user_ids` — a identidade `X-On-Behalf-Of`. Cada resposta também retorna um `X-Request-ID` que você pode armazenar como chave de correlação.
* **Guardrails** - As decisões de política são registradas no mesmo fluxo de auditoria: resultados como `policy_violation` ou `throttled` e valores de `policy_action` de `warn`, `block` ou `escalate` fluem para a página de Guardrails, dando a você um caminho consistente de um relatório de uso até a ação exata que foi permitida, avisada, bloqueada ou escalada.

Fontes: [repositórios de prompts](https://docs.mka1.com/docs/prompt-repository), [limite de taxa](https://docs.mka1.com/docs/rate-limiting), [auditoria de uso](https://docs.mka1.com/docs/usage-auditing) e [habilidades](https://reference.mka1.com/reference#tag/skills).

## Fala e voz

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/text-to-speech-detail.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=f28fa5329e249f122e48e5ac4a1d9de7" alt="Detalhe de geração de texto para fala com saída de áudio" width="1999" height="1173" data-path="images/platform-getting-started/text-to-speech-detail.png" />

O MKA1 expõe a fala baseada em arquivos através do recurso `llm.speech` do SDK. Use `speak` para texto-para-fala e `transcribe` para fala-para-texto. Para conversas bidirecionais em tempo real, use o modo de voz avançado. O modo de voz avançado é coberto separadamente.

### Texto para fala

`speak` retorna um arquivo WAV completo. O corpo da resposta é áudio binário, e os cabeçalhos da resposta incluem `X-Language-Code`.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { SDK } from '@meetkai/mka1';
  import { writeFileSync } from 'node:fs';

  const mka1 = new SDK({ bearerAuth: 'Bearer <mka1-api-key>' });

  const { headers, result } = await mka1.llm.speech.speak({
    textToSpeechRequest: {
      text: 'Welcome to the MKA1 API speech guide.',
      language: 'en',
    },
  });
  // headers['x-language-code'] → ['en']

  const chunks = [];
  for await (const chunk of result) chunks.push(chunk);
  writeFileSync('speech.wav', Buffer.concat(chunks));
  ```

  ```python Python theme={null}
  res = sdk.llm.speech.speak(
      text="Welcome to the MKA1 API speech guide.",
      language="en",
  )
  # res.headers["x-language-code"] → ["en"]; res.result transmite os bytes WAV

  with open("speech.wav", "wb") as fh:
      fh.write(res.result.read())
  ```
</CodeGroup>

Para reprodução de baixa latência que começa antes de o arquivo completo estar pronto, use `speakStreaming` e escolha `mp3` (menor) ou `pcm` (sem compressão):

<CodeGroup>
  ```ts TypeScript theme={null}
  // Variante de baixa latência
  const streamed = await mka1.llm.speech.speakStreaming({
    textToSpeechStreamingRequest: {
      text: 'Start speaking this response as soon as audio is ready.',
      language: 'en',
      format: 'mp3',
    },
  });
  ```

  ```python Python theme={null}
  # Variante de baixa latência — note format_ com underscore no final
  streamed = sdk.llm.speech.speak_streaming(
      text="Start speaking this response as soon as audio is ready.",
      language="en",
      format_="mp3",
  )
  ```
</CodeGroup>

### Fala para texto

`transcribe` aceita um arquivo de áudio (FLAC, MP3, MP4, M4A, OGG, WAV, WebM, PCM e mais) e retorna a transcrição junto com o idioma detectado e a confiança:

<CodeGroup>
  ```ts TypeScript theme={null}
  import { openAsBlob } from 'node:fs';

  const result = await mka1.llm.speech.transcribe({
    language: 'en',
    prompt: 'This is a technical podcast about machine learning.',
    temperature: 0.2,
    requestBody: { file: await openAsBlob('episode.wav') },
  });

  console.log(result.text);       // transcrição
  console.log(result.confidence); // confiança da detecção
  ```

  ```python Python theme={null}
  with open("episode.wav", "rb") as fh:
      result = sdk.llm.speech.transcribe(
          file={"file_name": "episode.wav", "content": fh.read()},
          language="en",
          prompt="This is a technical podcast about machine learning.",
          temperature=0.2,
      )

  print(result.text)        # transcrição
  print(result.confidence)  # confiança da detecção
  ```
</CodeGroup>

Para separação de múltiplos falantes, defina `includeSpeakerData: true` (requer áudio WAV ou PCM). A resposta então inclui um array `speakers` com segmentos rotulados e tempos `offset_ms` / `duration_ms`.

Arquivos fonte: [fala](https://docs.mka1.com/docs/speech), [saída multimodal](https://docs.mka1.com/docs/multimodal-output).

## Avaliar e observar

Quando algo funciona, o MKA1 ajuda você a medi-lo e observá-lo em produção.

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/eval-suite.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=9f1dbcc0f00e950bddd7439c92319f27" alt="Uma suíte de avaliação com conjunto de dados, avaliador e versões" width="1999" height="1173" data-path="images/platform-getting-started/eval-suite.png" />

* **Evals** - Monte uma suíte de avaliação a partir de conjuntos de dados, prompts e avaliadores, e depois lance execuções duráveis contra um ou mais modelos. Acompanhe a precisão e as pontuações por amostra, e compare modelos em um placar. Use para escolher um modelo e para pegar regressões antes que sejam lançadas.
* **Sessions** - Cada execução de agente é registrada. Reproduza a transcrição (mensagens, raciocínio, chamadas de ferramentas) e percorra os eventos brutos para depurar exatamente o que um agente fez.
* **Uso e auditoria** - Revise o uso de tokens, requisições e armazenamento por org e equipe em **Admin → Usage**, e filtre por usuário final quando enviar `X-On-Behalf-Of`. Cada resposta também retorna um `X-Request-ID` que você pode armazenar como chave de correlação.

### Auditoria

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/audit.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=158bbbbb22bf6fdd81521b5b022203ee" alt="A visão de Audit do tráfego do gateway em Admin → Audit" width="1999" height="1013" data-path="images/platform-getting-started/audit.png" />

Audit (**Admin → Audit**) é a superfície de revisão do tráfego que passou pelo gateway. Administradores do cluster veem requisições de todas as organizações e equipes; administradores de organização veem a atividade da sua própria org. Pesquise por rota, caminho ou usuário; filtre por serviço, método, status, modelo ou estado de revisão; ou cole um `X-Request-ID` — retornado em cada resposta da API — para pular direto para a requisição exata. Marque entradas para revisão, agrupe requisições relacionadas em casos e exporte dados de resposta para análise offline.

### Alertas

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/alerts.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=6d6922ef40c295457b2a0be3e5b4a25d" alt="Endpoints de webhook de alertas em Admin → Alerts" width="1999" height="1004" data-path="images/platform-getting-started/alerts.png" />

Os alertas transformam falhas em webhooks. Em **Admin → Alerts**, registre uma URL de endpoint e escolha seu escopo: o cluster inteiro (administradores do cluster), sua organização (proprietários e administradores de org) ou uma única equipe — administradores de org podem mirar qualquer equipe, e membros de equipe podem gerenciar webhooks da sua própria equipe ativa. Inscreva o endpoint em um ou ambos os tipos de evento — `response.failed` (uma requisição de resposta falhou no provedor do modelo) e `gateway.request.failed` (qualquer requisição do gateway retornou um 5xx) — ou deixe a inscrição vazia para receber todos. Filtros opcionais restringem a entrega a chaves de API, códigos de erro ou modelos específicos.

Cada endpoint tem uma página de detalhes mostrando sua configuração, seu segredo de assinatura (revele, copie ou rotacione) e as entregas recentes com payloads e status succeeded / failed / pending. De lá você pode reenviar uma entrega, disparar um alerta de teste durante a integração, e editar, desabilitar ou excluir o endpoint — editar nunca muda o segredo de assinatura.

## Preços, orçamentos e uso

Cada requisição flui por um pipeline de faturamento: o uso registra os volumes, o livro de preços de modelos os converte em custos e os orçamentos aplicam limites sobre o resultado. Esta seção cobre os três.

### Preços

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/pricing.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=02fa4d0f64af96eaad31d93f0a7d67ba" alt="Formulário de adicionar preço de modelo em Admin → Pricing" width="1999" height="1010" data-path="images/platform-getting-started/pricing.png" />

Cada requisição é medida e precificada contra o livro de preços de modelos do seu cluster. Administradores do cluster mantêm o livro de preços em **Admin → Pricing**:

* **Moeda do cluster** - A moeda em que todo preço e orçamento é denominado.
* **Preços de modelos** - A tabela padrão do cluster, um preço por modelo. As dimensões de tarifa seguem a modalidade do modelo: tokens de entrada, saída, entrada em cache e raciocínio para LLMs; áudio e caracteres para fala; tarifas por imagem com níveis opcionais por tamanho; busca na web.
* **Substituições por org** - Preços por organização para quando uma org fatura diferente do padrão do cluster.
* **Tarifas efetivas** - Uma visão de resolução mostrando qual preço — padrão do cluster, substituição da org ou sem preço — cada modelo resolve para uma dada organização. Modelos sem preço faturam a 0.

Os preços são datados: salvar adiciona uma nova versão e nunca reescreve o custo passado. O gasto então aparece em dois lugares:

* **Admin → Usage** - Gasto total precificado a partir do livro de preços, detalhado por organização, equipe, chave de API e modelo — junto com os volumes subjacentes (veja Uso abaixo).
* **A API** - Consulte o gasto em qualquer intervalo de tempo, agrupado por modelo, chave de API, equipe, organização ou usuário final (a identidade `X-On-Behalf-Of`). Este é o alimentador para sistemas de faturamento; os Orçamentos (abaixo) aplicam limites contra o mesmo gasto.

<CodeGroup>
  ```ts TypeScript theme={null}
  const now = Math.floor(Date.now() / 1000);

  const spend = await mka1.usage.costs({
    startTime: now - 7 * 24 * 60 * 60, // últimos 7 dias (segundos unix)
    endTime: now,
    groupBy: 'model,api_key_id', // dimensões separadas por vírgula
  });
  // spend.data → [{ model, apiKeyId, teamId, externalUserId, orgId, cost }, …]
  ```

  ```python Python theme={null}
  import time

  now = int(time.time())
  spend = sdk.usage.costs(
      start_time=now - 7 * 24 * 3600,  # últimos 7 dias (segundos unix)
      end_time=now,
      group_by="model,api_key_id",  # dimensões separadas por vírgula
  )
  # spend.data → linhas com model, api_key_id, team_id, external_user_id, org_id, cost
  ```
</CodeGroup>

### Orçamentos

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/budgets.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=36094849ed0c62bf28bbccc30732211e" alt="Formulário de novo orçamento de organização em Admin → Budgets" width="1999" height="1016" data-path="images/platform-getting-started/budgets.png" />

Os orçamentos limitam o gasto total por período em uma organização ou uma chave de API. Crie e gerencie-os em **Admin → Budgets** — administradores de organização gerenciam os orçamentos da sua org, enquanto orçamentos de chaves de API hoje são geridos pelo administrador do cluster. Um orçamento tem três partes:

* **Período e limite** - Diário, semanal ou mensal, com um limite na moeda do cluster. As janelas de gasto reiniciam nos limites do calendário UTC.
* **Limiares** - Porcentagens únicas do limite, cada uma pareada com uma ação: `alert` (notificar) ou `block` (rejeitar novas requisições). Um orçamento que passou de um limiar de bloqueio mostra Blocked nas colunas ao vivo Spend e Status.
* **Webhook de alerta (opcional)** - Uma URL mais um segredo de assinatura HMAC que recebe as notificações de limiar.

Cada linha de orçamento mostra o gasto ao vivo contra seu limite; abra o histórico de um orçamento para revisar os eventos de limiar do período, e edite ou exclua orçamentos conforme as necessidades mudam. Os orçamentos têm duas propriedades: orçamentos de cluster são tetos do operador (somente leitura para administradores de org), enquanto orçamentos de org são autoimpostos. A aplicação é de melhor esforço e fail-open, então dimensione os limites com margem.

As mesmas operações estão disponíveis pela API — conceda à chave os scopes de Orçamentos exclusivos de administrador (`read:budgets` / `write:budgets`) no assistente de chaves do Passo 4.

<CodeGroup>
  ```ts TypeScript theme={null}
  // Orçamento mensal próprio em uma chave de API: avisar aos 80%, bloquear aos 100%
  await mka1.budgets.setApiKey({
    apiKeyId: 'ak_…',
    requestBody: {
      period: 'monthly',
      limit: 250, // na moeda do seu cluster — veja budgets.getCurrency()
      thresholds: [
        { pct: 80, action: 'alert' },
        { pct: 100, action: 'block' },
      ],
      webhookUrl: 'https://your-app.example.com/hooks/budget',
      webhookSecret: process.env.MKA1_WEBHOOK_SECRET,
    },
  });

  const budgets = await mka1.budgets.getApiKey({ apiKeyId: 'ak_…' });
  const events = await mka1.budgets.apiKeyEvents({ apiKeyId: 'ak_…' });
  await mka1.budgets.deleteApiKey({ apiKeyId: 'ak_…', owner: 'org' });

  // Variantes no nível da org: budgets.setOrg / getOrg / deleteOrg / orgEvents ({ orgId, … })
  ```

  ```python Python theme={null}
  sdk.budgets.set_api_key(
      api_key_id="ak_…",
      period="monthly",
      limit=250,
      thresholds=[
          {"pct": 80, "action": "alert"},
          {"pct": 100, "action": "block"},
      ],
  )

  budgets = sdk.budgets.get_api_key(api_key_id="ak_…")
  events = sdk.budgets.api_key_events(api_key_id="ak_…")
  sdk.budgets.delete_api_key(api_key_id="ak_…", owner="org")

  # Variantes no nível da org: set_org / get_org / delete_org / org_events (org_id=…)
  ```
</CodeGroup>

### Uso

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/usage.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=cbc37240ac560ee4186fc863d45db8ea" alt="O painel de Usage com tokens ao longo do tempo e detalhamentos por modelo em Admin → Usage" width="1999" height="1002" data-path="images/platform-getting-started/usage.png" />

O uso é o livro de volumes por trás dos preços e orçamentos — os tokens, contagens de requisições e armazenamento de cada requisição são medidos por organização, equipe, chave de API e usuário final. Ele vive em dois lugares:

* **No console** - **Admin → Usage** mostra um gráfico de tokens ao longo do tempo (24h / 7d / 30d), detalhamentos por categoria (Responses, Completions, Embeddings, Classify, Extract) com tokens de entrada/saída e contagens de requisições por modelo, linhas por usuário final, armazenamento de arquivos e vetores, e operações de sandbox — tudo exportável como CSV. A seção de gasto precifica esses volumes a partir do livro de preços de modelos (veja **Preços** acima).
* **Pela API** - Endpoints por categoria (`llm.usage.responses`, `completions`, `conversations`, `embeddings`, `extract`, `classify`, `vectorStores`, `files`) retornam séries agrupadas no tempo. Escolha um `bucket_width`, filtre por `models`, `user_ids` ou `external_user_ids` (a identidade `X-On-Behalf-Of`) e agrupe por `model`, `api_key_id`, `user_id`, `org_id` ou `background` para relatórios por dimensão.

<CodeGroup>
  ```ts TypeScript theme={null}
  const now = Math.floor(Date.now() / 1000);

  const usage = await mka1.llm.usage.responses({
    startTime: now - 7 * 24 * 60 * 60, // últimos 7 dias (segundos unix)
    endTime: now,
    bucketWidth: '1d',
    groupBy: 'model',
  });
  // usage.data → um bucket por dia, cada um com resultados por modelo
  // (tokens de entrada/saída, contagens de requisições)
  ```

  ```python Python theme={null}
  import time

  now = int(time.time())
  usage = sdk.llm.usage.responses(
      start_time=now - 7 * 24 * 3600,  # últimos 7 dias (segundos unix)
      end_time=now,
      bucket_width="1d",
      group_by="model",
  )
  # usage.data → um bucket por dia, cada um com resultados por modelo
  ```
</CodeGroup>

## Serving

O Serving transforma os aceleradores do seu cluster — GPU, NPU ou TPU — em endpoints de inferência com autoescalonamento para os modelos que você escolher. Ele vive na sua própria seção Serving da barra lateral (administradores de organização e de cluster), e sua organização precisa ser provisionada para serving pelo operador do cluster antes do primeiro uso. Seis blocos de construção:

* **Deployments** - Um modelo servido atrás de um endpoint de inferência em aceleradores dedicados, apoiado por vLLM ou SGLang. Mudanças de configuração geram uma nova revisão — reverta para qualquer revisão anterior a qualquer momento — enquanto mudanças de escalonamento se aplicam no lugar. A URL do endpoint é atribuída quando a implantação está pronta, e a autenticação do endpoint exige que os chamadores apresentem uma chave de API válida. Cada implantação expõe status, réplicas, revisões, logs e métricas.
* **Models** - Registre um modelo servível por nome e origem, opcionalmente fixando um branch, tag ou revisão de commit para implantações reproduzíveis.
* **Images** - Construa imagens de contêiner personalizadas (imagem OCI base, pacotes apt, comandos de build) para engines de serving e trabalhos de fine-tuning; as implantações usam por padrão a imagem padrão do engine.
* **Fine-tune jobs** - Treine nos aceleradores do cluster: um modelo base, um conjunto de dados, uma estratégia (LoRA por padrão, ou fine-tuning completo) e hiperparâmetros livres. Acompanhe logs e a linha do tempo de eventos, colete checkpoints e cancele a qualquer momento.
* **Accelerators** - Os tipos de aceleradores disponíveis para sua organização (p. ex. A100, H100) e seus limites por tipo.
* **Volumes & secrets** - Volumes persistentes (de tamanho fixo, ou elásticos que crescem sob demanda) e segredos como um hf-token, injetados nas implantações como variáveis de ambiente.

O autoescalonamento é por implantação: réplicas mínimas e máximas, réplicas de reserva mantidas prontas para absorver picos, um teto de requisições concorrentes roteadas a uma réplica antes de escalar para fora, e uma janela de ociosidade (2–1200 segundos) antes de reduzir a escala.

<CodeGroup>
  ```ts TypeScript theme={null}
  // 1. Registre o modelo a servir (fixe uma revisão para implantações reproduzíveis)
  await mka1.serving.models.register({
    modelRegister: { name: 'qwen-7b', source: 'Qwen/Qwen2.5-7B-Instruct' },
  });

  // 2. Implante-o atrás de um endpoint com autoescalonamento
  const deployment = await mka1.serving.deployments.create({
    deploymentCreate: {
      name: 'qwen-7b-prod',
      model: 'qwen-7b',
      engine: 'vllm',
      accelerator: { type: 'H100', count: 1, fallback: ['A100'] },
      scaling: { minContainers: 1, maxContainers: 4, maxConcurrentInputs: 32 },
      engineArgs: ['--max-model-len', '8192'],
      endpointAuth: true,
    },
  });
  // a URL do endpoint aparece na implantação quando ela está pronta

  // 3. Opere-o
  await mka1.serving.deployments.updateScaling({
    deploymentId: deployment.id,
    scaling: { minContainers: 2, maxContainers: 8 }, // aplica-se no lugar — sem nova revisão
  });

  const logs = await mka1.serving.deployments.getLogs({ deploymentId: deployment.id, tail: 100 });

  await mka1.serving.deployments.rollback({
    deploymentId: deployment.id,
    deploymentRollbackRequest: { revision: 1 }, // mudanças de configuração geram revisões
  });
  ```

  ```python Python theme={null}
  # 1. Registre o modelo a servir (fixe uma revisão para implantações reproduzíveis)
  sdk.serving.models.register(name="qwen-7b", source="Qwen/Qwen2.5-7B-Instruct")

  # 2. Implante-o atrás de um endpoint com autoescalonamento
  deployment = sdk.serving.deployments.create(
      name="qwen-7b-prod",
      model="qwen-7b",
      engine="vllm",
      accelerator={"type": "H100", "count": 1, "fallback": ["A100"]},
      scaling={"min_containers": 1, "max_containers": 4, "max_concurrent_inputs": 32},
      engine_args=["--max-model-len", "8192"],
      endpoint_auth=True,
  )
  # a URL do endpoint aparece na implantação quando ela está pronta

  # 3. Opere-o
  sdk.serving.deployments.update_scaling(
      deployment_id=deployment.id,
      min_containers=2,
      max_containers=8,  # aplica-se no lugar — sem nova revisão
  )

  logs = sdk.serving.deployments.get_logs(deployment_id=deployment.id, tail=100)

  sdk.serving.deployments.rollback(deployment_id=deployment.id, revision=1)
  ```
</CodeGroup>

## Juntando tudo: construa um agente de ponta a ponta

Os blocos de construção se compõem. Este é o fluxo principal de ponta a ponta: indexe conhecimento, conecte ferramentas, empacote uma habilidade, monte um agente, execute-o e rastreie o resultado.

<img src="https://mintcdn.com/meetkaiinc/6LyFGcL-YnhBj_CK/images/platform-getting-started/new-agent-tools.png?fit=max&auto=format&n=6LyFGcL-YnhBj_CK&q=85&s=ff3533965814ffdc566b67ce4f77c885" alt="Formulário de criação de agente com ferramentas integradas" width="1999" height="1173" data-path="images/platform-getting-started/new-agent-tools.png" />

1. **Indexe conhecimento.** Envie seus documentos como Files e anexe-os a um Vector Store para que o agente possa fundamentar respostas no seu conteúdo (veja *Arquivos, lojas vetoriais e recuperação*).
2. **Conecte ferramentas.** Registre um servidor MCP (ou use ferramentas integradas como `web_search`) para que o agente possa agir e buscar dados ao vivo (veja *Agentes, ferramentas e MCP*).
3. **Empacote uma habilidade.** Agrupe comportamento reutilizável atrás de um SKILL.md e envie-o em **Skills**, depois anexe-o.
4. **Monte o agente.** Crie um agente salvo com um modelo, instruções e esse conjunto de ferramentas. Você configura o agente uma vez, então não reconstrói a requisição a cada chamada.
5. **Execute-o.** Execute o agente com entrada nova a partir do console ou de `POST /api/v1/agents/{id}/runs`. Cada execução persiste sua entrada e a resposta do gateway.
6. **Rastreie a execução.** Abra **Sessions** para reproduzir a transcrição e confirmar que o agente chamou as ferramentas certas.

## Referência e suporte

Mantenha isto por perto enquanto constrói:

| Recurso                                         | Onde                                                                                             |
| :---------------------------------------------- | :----------------------------------------------------------------------------------------------- |
| Referência completa da API (OpenAPI + "Try it") | [Referência da API](https://docs.mka1.com/api-reference/introduction)                            |
| Autenticação                                    | [docs.mka1.com/docs/authentication](https://docs.mka1.com/docs/authentication)                   |
| Gerar uma resposta                              | [docs.mka1.com/docs/generate-a-response](https://docs.mka1.com/docs/generate-a-response)         |
| Arquivos e lojas vetoriais                      | [docs.mka1.com/docs/files-and-vector-stores](https://docs.mka1.com/docs/files-and-vector-stores) |
| Gerenciar agentes                               | [docs.mka1.com/docs/managing-agents](https://docs.mka1.com/docs/managing-agents)                 |
| Ferramentas MCP                                 | [docs.mka1.com/docs/mcp-tools](https://docs.mka1.com/docs/mcp-tools)                             |
| CLI                                             | [docs.mka1.com/docs/cli/introduction](https://docs.mka1.com/docs/cli/introduction)               |
| SDK Python                                      | [pypi.org/project/meetkai-mka1/](https://pypi.org/project/meetkai-mka1/)                         |
| SDK C#                                          | [nuget.org/packages/MeetKai.MKA1/](https://www.nuget.org/packages/MeetKai.MKA1/)                 |
| SDK TypeScript                                  | [npmjs.com/package/@meetkai/mka1](https://www.npmjs.com/package/@meetkai/mka1)                   |

<Note>
  **Recapitulação rápida**

  1. Aceite o convite do cluster → você é proprietário de uma nova organização.
  2. Crie uma equipe e convide colegas.
  3. Gere uma chave de API nessa equipe (copie o segredo uma vez).
  4. Instale um SDK e autentique-se com `Authorization: Bearer`.
  5. Chame `responses.create` — depois componha conversas, memória, RAG, agentes, ferramentas e fala na sua aplicação.
</Note>

Bem-vindo a bordo. Agora vá construir algo.
