---
title: "SDK Authentication"
description: "Aeontel SDK authentication: secret keys, publishable keys, and session tokens."
section: "Libraries"
group: "SDK"
---

# SDK Authentication

The SDK accepts three kinds of credentials, picked by ID prefix:

| Prefix    | Kind                                           | Where it's safe            |
| --------- | ---------------------------------------------- | -------------------------- |
| `sec_...` | Secret key — full workspace access             | Server only                |
| `pub_...` | Publishable key — scoped, read-only by default | Safe to expose in browsers |
| `tok_...` | Session token — scoped per user/device         | Server or client           |

```ts
import Aeontel from "@aeontel/sdk";

const server = new Aeontel("sec_...");
const browser = new Aeontel("pub_...");
const scoped = new Aeontel("tok_...");
```

If you omit the argument, the SDK reads `AEONTEL_API_KEY` from `process.env`.

## Cookie auth

Pass `null` to let the browser attach the session cookie set by `/api/auth/*`. Requires `credentials: "include"` so the cookie is sent cross-origin.

```ts
const client = new Aeontel(null, {
  baseURL: "https://api.aeontel.com",
  credentials: "include",
});
```

This is how the platform SPA talks to the API — the user is already signed in, so no key is needed.

## Internal service binding

From a Cloudflare Worker on the same account, skip public HTTP entirely and pass the bound `Fetcher`.

```ts
const client = new Aeontel(null, { binding: env.AEONTEL_API });
```

When `binding` is set, `baseURL` is ignored. Requests are built as `https://api.internal<path>`.

## Trusted internal callers

Some internal endpoints require identity via headers. Pass them once at construction.

```ts
const client = new Aeontel(null, {
  binding: env.AEONTEL_API,
  headers: {
    "x-internal-caller": "aeontel-email",
    "x-internal-secret": env.INTERNAL_API_SECRET,
  },
});
```
