---
title: "Call an external API without exposing its key: the while.sh docs"
url: https://while.sh/en/docs/building-blocks/api-connections/
updated: 2026-11-09
---

# API connections

Your app calls an external API, like Stripe, Brevo or an AI, through an address while gives it. while adds the key: neither your app nor your agent sees it.

> You, to your agent: Connect Brevo to send the emails, without putting the key in the code.

## What your agent writes

Your agent writes it in while.yaml, at the root of your app:

```yaml titre="while.yaml"
services:
  - name: web
    port: 3000
    connections: [brevo]
```

## What your app receives

Your app receives these environment variables at every deployment:

| Variable | What it holds |
|---|---|
| `<NAME>_URL` | The connection's address: BREVO_URL for a brevo connection. The key isn't in it, while adds it. |

## When to use it

Use it to call an external API whose key while keeps. For an AI (Anthropic, OpenAI, Mistral), declare the connection with its model (`declare_connection`): its generations go through automatically. For Google, there are two paths, with a key or without a key (federation), and the choice belongs to a person.

## How it works

Your app calls an external API (Stripe, Brevo, Pennylane…) through an address like `BREVO_URL`, and while adds the key: neither the app nor the agent sees it. Each call is traced, and the connection locks onto what was used after 7 days of learning.

## What to know

The connection is declared first (`declare_connection`), then a person approves it. A project token can declare it for its project: it is then a request, approved by a person who can configure connections. The secret is entered in the interface or through the API, never through MCP.

while authenticates with a key (header or parameter), Basic, Bearer, OAuth2 (client credentials, with a discovered OIDC issuer), a session by service identifier, or a JWT it signs with the connection's private key (jwt: exchange, `client_assertion` or direct). Templates exist for Google (a service account and its scopes), Salesforce and Microsoft.

During learning, writes (POST, PUT, PATCH, DELETE) are blocked, except on a `post_read` path or through an approved rule. Once the connection is locked, what falls outside the rules gets a 403, and the agent is notified (`sh.while.connection.refused`). An "approve each call" rule answers 202 and waits for an approval.

An API without IPv6 (Open-Meteo…) is also reached through a connection: declare it for your project, even with a project token; a person approves it, and while reaches it over IPv4 through its relay, with nothing to do in the app.

There are two paths to Google, and the choice belongs to a person. With a key (jwt connection, google template), a service account key is kept by while, never in the app, but it is a long-lived key, to be changed if it leaks. With OIDC identity federation (Workload Identity Federation at Google, federated credential at Azure) (federated connection), it is the same thing without any key, and only production calls Google. Federation also has a box on the binding, unchecked by default: checked, every production deployment of the project waits for the click of an approving person (someone other than the one who requests it, if there is another), and only approved code acts at Google.

## Pricing

These prices are the same on every plan, excluding VAT:

| Resource | Price | Details |
|---|---|---|
| Gateway calls | €0.30 per 1,000 calls | beyond 500,000 per month, Pro plan |

## Your agent's MCP tools

Your agent handles it with the `declare_connection`, `list_connections` and `call_connection` tools.

## Guides

- [Connect Stripe, Brevo or any API to your app with no key in the code, from your AI agent](/en/guides/api-keys-out-of-code/)
- [Call Claude, GPT or Mistral from your app without exposing the key, with your AI agent](/en/guides/call-llm-api-without-exposing-key/)
