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

# Respostas HTTP

> Controle o status code e headers das suas respostas com o response builder: status personalizados, headers custom e comportamento em MCP.

## Comportamento padrão

Quando seu handler retorna um objeto simples, a plataforma responde com `200 OK` e `Content-Type: application/json`:

```typescript theme={null}
handler: async (input) => {
  return { nome: "Maria", saldo: 150.00 };
}
// → 200 OK
```

Quando você precisa de um status code diferente ou headers personalizados, use o **response builder**.

## Response builder

Importe `response` de `@jelou/functions`:

```typescript theme={null}
import { define, response, z } from "@jelou/functions";
```

### Status code personalizado

```typescript theme={null}
export default define({
  description: "Cria um usuário",
  input: z.object({ nome: z.string(), email: z.string().email() }),
  output: z.object({ id: z.string(), nome: z.string() }),
  handler: async (input) => {
    const usuario = await criarUsuario(input);
    return response
      .status(201)
      .json({ id: usuario.id, nome: usuario.nome });
  },
});
```

### Headers personalizados

```typescript theme={null}
handler: async (input) => {
  return response
    .header("X-Request-Id", crypto.randomUUID())
    .header("Cache-Control", "max-age=300")
    .json({ dados: [] });
}
```

### Múltiplos headers de uma vez

```typescript theme={null}
handler: async (input) => {
  return response
    .headers({
      "X-Request-Id": crypto.randomUUID(),
      "Cache-Control": "no-store",
    })
    .json({ ok: true });
}
```

### Encadeamento completo

O builder é **imutável** — cada método retorna uma nova instância:

```typescript theme={null}
handler: async (input) => {
  return response
    .status(201)
    .header("Location", `/usuarios/${input.id}`)
    .json({ id: input.id, nome: input.nome });
}
// → 201 Created
// → Location: /usuarios/abc123
```

## API

| Método                         | Descrição                              |
| ------------------------------ | -------------------------------------- |
| `response.status(code)`        | Define o status HTTP (padrão: 200)     |
| `response.header(name, value)` | Adiciona um header                     |
| `response.headers(init)`       | Adiciona múltiplos headers             |
| `response.json(body)`          | Finaliza com um body JSON              |
| `response.noContent()`         | Finaliza com `204 No Content` sem body |

<Note>
  `.json()` e `.noContent()` são os métodos terminais — depois de chamá-los você obtém uma resposta final, não um builder.
</Note>

## Exemplos práticos

<Tabs>
  <Tab title="201 Created">
    ```typescript theme={null}
    handler: async (input) => {
      const ticket = await criarTicket(input);
      return response
        .status(201)
        .header("Location", `/tickets/${ticket.id}`)
        .json({ ticketId: ticket.id, estado: "aberto" });
    }
    ```
  </Tab>

  <Tab title="404 Not Found">
    ```typescript theme={null}
    handler: async (input) => {
      const cliente = await buscarCliente(input.telefone);
      if (!cliente) {
        return response
          .status(404)
          .json({ error: "not_found", message: "Cliente não encontrado" });
      }
      return { nome: cliente.nome, saldo: cliente.saldo };
    }
    ```
  </Tab>

  <Tab title="Cache headers">
    ```typescript theme={null}
    handler: async (input) => {
      const produtos = await listarProdutos(input.categoria);
      return response
        .header("Cache-Control", "public, max-age=300")
        .json({ produtos, total: produtos.length });
    }
    ```
  </Tab>

  <Tab title="204 No Content">
    ```typescript theme={null}
    handler: async (input, ctx) => {
      await deletarRecurso(input.id);
      return response.noContent();
    }
    // → 204 No Content (sem body)
    ```
  </Tab>
</Tabs>

## Validação de output

Quando usa `response.json(body)` com schema `output`, a validação se aplica ao **body**. A validação nunca bloqueia a resposta.

## Comportamento em MCP

Quando invocado via MCP (agentes IA no Brain Studio):

* O **body** é emitido como `structuredContent`
* **Status code** e **headers** são **ignorados**
* O body também é enviado como texto JSON para compatibilidade

<Tip>
  Não precisa condicionar seu código para HTTP vs MCP — use o response builder normalmente.
</Tip>

## Limitações

| Limitação               | Detalhe                                                              |
| ----------------------- | -------------------------------------------------------------------- |
| JSON ou vazio           | Apenas `.json()` e `.noContent()` — sem `.text()`, `.html()`         |
| Sem Web Response nativo | Retornar `new Response()` de `define()`/`app()` não funciona         |
| Content-Type fixo       | Sempre `application/json` em `.json()`                               |
| OpenAPI                 | Spec em `/openapi.json` documenta apenas resposta `200` por enquanto |
