---
title: "Authentication"
description: "How to authenticate API requests with a Bearer token, store and rotate it safely, read a 401 response, and connect Facebook Pages and Instagram via OAuth."
canonical: "https://omnichannels.ai/developers/authentication/"
language: "en"
updated: "2026-10-10"
publisher: "BroadNet Technologies"
brand: "OmniChannels.ai"
section: "Get started"
---

# Authentication

Canonical: https://omnichannels.ai/developers/authentication/
Language: en
Publisher: OmniChannels.ai by BroadNet Technologies

Every REST request carries your account's access token in an `Authorization: Bearer` header. The same token works for every channel, and a missing or invalid token is rejected with HTTP `401`.

## How authentication works

| Item | Detail |
| --- | --- |
| Scheme | HTTP Bearer token |
| Header | `Authorization: Bearer <your token>` |
| Scope | One token per account. It acts with that account's permissions, sender IDs and balance. |
| Issued by | Our team, with your test or production credentials. A permanent key is issued by your account admin or master account. |
| Token endpoint | None. The API has no call that exchanges a username and password for a token. |
| Transport | HTTPS only. Keep certificate verification on. |

```bash title="cURL"
curl -X POST https://api.broadnet.me/sms/identify \
  -H "Authorization: Bearer $BROADNET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "message": "Hello from OmniDemo" }'
```

```js title="Node.js"
const res = await fetch("https://api.broadnet.me/sms/identify", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BROADNET_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ message: "Hello from OmniDemo" }),
});
console.log(res.status, await res.json());
```

```python title="Python"
import os
import requests

session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['BROADNET_TOKEN']}"

r = session.post(
    "https://api.broadnet.me/sms/identify",
    json={"message": "Hello from OmniDemo"},
    timeout=15,
)
print(r.status_code, r.json())
```

```php title="PHP"
<?php
$ch = curl_init("https://api.broadnet.me/sms/identify");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("BROADNET_TOKEN"),
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode(["message" => "Hello from OmniDemo"]),
]);
echo curl_exec($ch);
curl_close($ch);
```

## Store the token safely

The token is a send credential: anyone who holds it can send messages and spend your balance.

- Keep it in a secrets manager or an environment variable on your servers.
- Never put it in source control, mobile apps, browser JavaScript, logs or support tickets.
- Call the API from your backend only. If a web or mobile client needs to trigger a message, have it call your server, which then calls the API.
- Give each environment (development, staging, production) its own credentials where your account allows it, so a leak in one does not expose the others.
- **Resellers:** keep credentials separate per customer sub-account so that revoking one never affects another.

## Rotate or revoke a token

There is no self-service rotation endpoint in the API. To rotate a token, or to revoke one that may have leaked, contact your account admin or our support team. They revoke the old key and issue a new one.

A safe rotation sequence:

1. Request a new token and add it to your secrets store next to the old one.
2. Deploy the new token to every service that calls the API.
3. Confirm that traffic succeeds with the new token, for example by watching for `401` responses.
4. Ask for the old token to be revoked.

For AI agents connected through MCP, use temporary keys while you experiment. See [MCP server](/developers/mcp/).

## What a 401 looks like

A missing or invalid token is rejected at the API gateway, before the request reaches the API. The response is `401 Unauthorized` with a two-field JSON body:

```json title="401 Unauthorized"
{
  "error": "Unauthorized",
  "message": "Missing Authorization token"
}
```

Errors raised by the API itself (for example a `400` validation error) use a different, five-field body. A `403` means the token is valid but not allowed to call that operation. Both are covered in [Errors and limits](/developers/errors-and-limits/).

Do not retry a `401` or `403`. Fix the token or ask us to enable the operation, then send again.

## IP allow-listing

REST API access is controlled by the Bearer token. IP allow-listing applies to SMPP binds: the source IPs for each bind are agreed and allow-listed when we provision it. See [SMPP](/developers/smpp/).

## OAuth for Facebook Pages and Instagram

OAuth is used for one thing only: connecting your Facebook Page or Instagram professional account so the platform can message on its behalf. Your API calls still use the Bearer token.

| Channel | Endpoint | What it returns |
| --- | --- | --- |
| Messenger | `POST /messenger/oauth/generate-link` | An encrypted onboarding link to connect a Facebook Page |
| Instagram | `POST /instagram/oauth/generate-link` | An encrypted onboarding link to connect an Instagram account |
| WhatsApp | `POST /whatsapp/generate-link` | An encrypted Meta Embedded Signup link (returns `201`) |

Open the link as the Page or business admin and complete Meta's consent screens. The calls take no request body; your identity comes from the token.

```bash title="cURL"
curl -X POST https://api.broadnet.me/messenger/oauth/generate-link \
  -H "Authorization: Bearer $BROADNET_TOKEN"
```

## Legacy credentials

Older SMPP-era integrations may use the legacy HTTP API under `/websmpp`, which takes a username and password as request parameters. Credentials in URLs end up in server and proxy logs, so new integrations should use the Bearer-token REST API described here.

## Next steps

- [Quickstart](/developers/quickstart/): send your first SMS with your token.
- [Errors and limits](/developers/errors-and-limits/): error bodies, retries and rate limits.
- [Messenger](/developers/messenger/) and [Instagram](/developers/instagram/): connect a Page or account, then send.
