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

# Evervault

> Fill Evervault Browser Tokens in a Notte session

> [!TIP]
>
> Read [the Notte skill](https://notte.cc/skill.md) and follow its setup instructions when setting up Notte or building browser automation. This is the shared source for CLI setup, authentication, and the browser-to-code workflow.

[Evervault Browser Tokens](https://docs.evervault.com/browser-tokens) turn encrypted card data and credentials into format-preserving stand-ins for an agent to type. Evervault's browser proxy replaces each token with the real value, but only on its way to the hostnames you allow. Use it as a Notte [secret proxy](https://docs.notte.cc/features/sessions/secret-proxies/overview.md).

> [!WARNING]
>
> Evervault's browser proxy does not mask responses. If a listed site sends a real value back, for example an endpoint that echoes the card number, the real value reaches the browser, and from there the agent, screenshots, recordings and network logs. Only list hosts that do not return the real values. See [Mask real values in responses](#mask-real-values-in-responses).

## Prerequisites

* An Evervault app with Browser Tokens, and its app ID and API key.
* The data to fill, encrypted with Evervault (for example with [Card Collection](https://docs.evervault.com/cards/card-collection)).
* The hostnames that receive the data: the payment provider or iframe host, not only the merchant's site. They must be HTTPS hosts: Evervault's browser proxy only handles `CONNECT` tunnels, so it rejects plain-HTTP requests even with a valid token.
* For the example below: `httpx` in Python, or the built-in `fetch` in Node.

## Map Evervault's values to the secret entry

Each `POST /browser-tokens` call returns the stand-ins (`data[].value`) and a `proxyConfiguration` for Evervault's browser proxy. Use it like this:

| Secret entry field | Value |
| - | - |
| `server` | `https://` + `proxyConfiguration.hostname` + `:` + `proxyConfiguration.port`, for example `https://us-va.browser.relay.evervault.app:443` (US) or `https://eu-ie.browser.relay.evervault.app:443` (EU) |
| `username` | `proxyConfiguration.username`: your Evervault app ID (`app_...`). It does not change, so you can save it. |
| `password` | `proxyConfiguration.password`: a short-lived token issued with each batch of tokens. Send it with each session. |
| `ca_certificate` | Evervault's root CA certificate (`CN=relay.evervault.com`), the single PEM certificate at [ca.evervault.com](https://ca.evervault.com). The session's `secret_proxy.ca_sha256` shows its SHA-256 fingerprint. |
| `hosts` | Exactly the `target` values of the tokens' `permissions`. Both use the same rules: exact hostnames or a leading `*.` wildcard. |

> [!WARNING]
>
> Keep `hosts` and `permissions[].target` identical. Notte sends every host in `hosts` to Evervault, but Evervault only swaps tokens for hosts in `permissions`. A host missing from `permissions` is tunneled through without interception and receives the stand-in.

The tokens and the proxy password stop working when the `ttl` expires. Evervault accepts a `ttl` of at most 900 seconds (15 minutes) and answers `400` to a higher value, so create tokens just before the agent fills them, or create a new batch and a new session when it runs out.

If the password is wrong or has expired, Evervault refuses the connection (`407`) and requests to the listed hosts fail. Requests to every other host keep working. See [If your secret proxy is unavailable](https://docs.notte.cc/features/sessions/secret-proxies/overview.md#if-your-secret-proxy-is-unavailable).

If you [save the configuration in the console](https://docs.notte.cc/features/sessions/secret-proxies/overview.md#save-the-configuration-in-the-console) with the Evervault preset, save the server, username (your app ID), CA certificate and hosts, and send only the `password` with each session.

## Share the exit IP

By default, Evervault sends requests to the listed hosts from its own datacenter IP addresses, so the listed hosts see a different IP address than the rest of the session's browsing.

To give every host the same IP, send Evervault's outgoing traffic through Notte's proxy gateway with `proxySettings` of `type: "custom"`:

1. Mint a [gateway credential](https://docs.notte.cc/features/sessions/secret-proxies/overview.md#share-the-exit-ip) with a `sticky_session` and a `country`.
2. Pass it in `proxySettings` when you create the tokens:

| `proxySettings` field | Value |
| - | - |
| `type` | `custom` |
| `scheme` | `https` |
| `hostname` | `proxy.notte.cc` |
| `port` | `443` |
| `username`, `password` | The `username` and `password` of the gateway credential |

3. Start the session with the same `sticky_session` and `country` on its `notte` entry.

Requests to the listed hosts and the rest of the browsing then exit from the same IP.

> [!NOTE]
>
> Evervault accepts egress credentials of up to 256 characters, and the gateway username grows with your `sticky_session`. Keep `sticky_session` to 32 characters or fewer: a 14-character value gives a username of about 150 characters.

## Mask real values in responses

Evervault's browser proxy does not replace real values in responses, and Notte does not change responses either. A listed site that sends a real value back, such as an endpoint that echoes the card number, returns the real value to the browser. Only list hosts that do not return the values you swap. See [Mask real values in responses](https://docs.notte.cc/features/sessions/secret-proxies/overview.md#mask-real-values-in-responses).

## Example

This example fills a card number and CVV on `api.stripe.com`, with Evervault's egress going through the session's exit:

```python evervault_flow.py theme={null}
import os

import httpx
from notte_sdk import NotteClient
from notte_sdk.types import NotteProxy, ProxyGeolocationCountry, ProxySettings, SecretProxy

STICKY_SESSION = "checkout-4821"

# 1. Mint a Notte gateway credential pinned to one residential exit
gateway = httpx.post(
    "https://api.notte.cc/proxies/gateway/credentials",
    headers={"Authorization": f"Bearer {os.environ['NOTTE_API_KEY']}"},
    json={"country": "us", "sticky_session": STICKY_SESSION},
).json()

# 2. Create Browser Tokens; Evervault's egress goes through Notte's gateway
tokens = httpx.post(
    "https://api.evervault.com/browser-tokens",
    auth=(os.environ["EVERVAULT_APP_ID"], os.environ["EVERVAULT_API_KEY"]),
    json={
        "data": [
            {"category": "card.number", "value": "ev:encrypted:...", "id": "card-number"},
            {"category": "card.cvv", "value": "ev:encrypted:...", "id": "card-cvv"},
        ],
        "permissions": [{"action": "decrypt", "target": "api.stripe.com"}],
        "ttl": 900,
        "proxySettings": {
            "type": "custom",
            "scheme": "https",
            "hostname": "proxy.notte.cc",
            "port": 443,
            "username": gateway["username"],
            "password": gateway["password"],
        },
    },
).json()
relay = tokens["proxyConfiguration"]

# 3. Start the session: same sticky_session and country, Evervault's relay for the listed host
proxies: list[ProxySettings] = [
    NotteProxy(country=ProxyGeolocationCountry.UNITED_STATES, sticky_session=STICKY_SESSION),
    SecretProxy(
        server=f"https://{relay['hostname']}:{relay['port']}",
        username=relay["username"],
        password=relay["password"],
        ca_certificate=httpx.get("https://ca.evervault.com").text,
        hosts=["api.stripe.com"],
    ),
]

client = NotteClient()
with client.Session(proxies=proxies) as session:
    # 4. The stand-in values the agent types
    stand_ins = {item["id"]: item["value"] for item in tokens["data"]}
    print(session.session_id, stand_ins)
```

```typescript evervault_flow.ts theme={null}
import { NotteClient, type NotteProxy, type SecretProxy } from 'notte-sdk';

const STICKY_SESSION = 'checkout-4821';

// 1. Mint a Notte gateway credential pinned to one residential exit
const gateway = (await (
  await fetch('https://api.notte.cc/proxies/gateway/credentials', {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.NOTTE_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ country: 'us', sticky_session: STICKY_SESSION }),
  })
).json()) as { username: string; password: string };

// 2. Create Browser Tokens; Evervault's egress goes through Notte's gateway
const evervaultAuth = Buffer.from(`${process.env.EVERVAULT_APP_ID}:${process.env.EVERVAULT_API_KEY}`).toString('base64');
const tokens = (await (
  await fetch('https://api.evervault.com/browser-tokens', {
    method: 'POST',
    headers: { Authorization: `Basic ${evervaultAuth}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({
      data: [
        { category: 'card.number', value: 'ev:encrypted:...', id: 'card-number' },
        { category: 'card.cvv', value: 'ev:encrypted:...', id: 'card-cvv' },
      ],
      permissions: [{ action: 'decrypt', target: 'api.stripe.com' }],
      ttl: 900,
      proxySettings: {
        type: 'custom',
        scheme: 'https',
        hostname: 'proxy.notte.cc',
        port: 443,
        username: gateway.username,
        password: gateway.password,
      },
    }),
  })
).json()) as {
  data: { id: string; value: string }[];
  proxyConfiguration: { hostname: string; port: number; username: string; password: string };
};
const relay = tokens.proxyConfiguration;

// 3. Start the session: same sticky_session and country, Evervault's relay for the listed host.
// sticky_session is not in the published NotteProxy type yet.
const exit: NotteProxy & { sticky_session: string } = {
  type: 'notte',
  country: 'us',
  sticky_session: STICKY_SESSION,
};
const secret: SecretProxy = {
  type: 'secret',
  server: `https://${relay.hostname}:${relay.port}`,
  username: relay.username,
  password: relay.password,
  ca_certificate: await (await fetch('https://ca.evervault.com')).text(),
  hosts: ['api.stripe.com'],
};

const client = new NotteClient();
await client.Session({ proxies: [exit, secret] }).use(async (session) => {
  // 4. The stand-in values the agent types
  const standIns = Object.fromEntries(tokens.data.map((item) => [item.id, item.value]));
  console.log(session.getId(), standIns);
});
```

Give the agent the stand-ins from `data[].value`. Evervault swaps them for the real values only on requests to `api.stripe.com`.

## Learn more

* [Evervault Browser Tokens](https://docs.evervault.com/browser-tokens)
* [Secret proxies](https://docs.notte.cc/features/sessions/secret-proxies/overview.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.