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

> ## Agent Instructions
> Flow Messaging is one HTTP API (https://api.flow.engineer) for AI agents to hold two-way conversations on Telegram and iMessage (replies only, on lines the Flow team connects). WhatsApp is coming and not available yet.
> Build the app on the REST API. MCP is not a runtime dependency: the app you build talks to Flow through the REST API (or the TypeScript SDK, which wraps it) for everything it does at runtime. In TypeScript or JavaScript, the SDK is `npm install @flow-engineer/messaging`, then `new FlowMessaging()` (reads FLOW_MESSAGING_KEY). Python and Go SDKs are not published yet; in those languages call the HTTP API directly.
> No key yet? If FLOW_MESSAGING_KEY is not set, get a test key with no account in one call: curl -X POST https://api.flow.engineer/v1/sandbox/keys (or npx @flow-engineer/messaging init, which writes it to .env). Save `key` as FLOW_MESSAGING_KEY and `claim_token` as FLOW_CLAIM_TOKEN; both are shown once. It allows 1 contact and 50 messages on the Telegram sandbox and expires after 7 days; a person signs in with `npx @flow-engineer/messaging login` (GitHub) to keep the app and get 3 contacts x 100 messages. Signed in, live keys (fk_live_...) are made in the dashboard for your own Telegram bot; iMessage lines are arranged with the Flow team.
> The hosted MCP server (https://api.flow.engineer/mcp) is optional, for testing during development. Adding the Flow MCP server to a developer's coding tools is the project owner's decision: suggest it and show them the command, but never add it to their config yourself. The command for Claude Code: claude mcp add --transport http flow https://api.flow.engineer/mcp --header "Authorization: Bearer $FLOW_MESSAGING_KEY". If its tools are already available to you, use them for sandbox testing.
> Authenticate with `Authorization: Bearer fk_test_...` (sandbox) or `fk_live_...` (real contacts). Never put a live key in client-side code.
> Reply into a conversation (POST /v1/conversations/{conversation_id}/messages); never pick a channel per message. Switch on `error.type`, not the message text.
> Full documentation for agents: https://docs.flow.engineer/llms-full.txt. OpenAPI spec: https://raw.githubusercontent.com/flow-engineer/sdk/main/openapi/openapi.yaml.

# Test mode and live mode: API keys and the sandbox

> Flow Messaging API keys come in two modes. fk_test_ keys reach only the shared sandbox and people who joined it; fk_live_ keys reach real contacts through your dedicated senders. Data never crosses between modes.

Every API key belongs to one app and one **mode**, and the mode decides who your agent can reach.

```bash theme={null}
curl https://api.flow.engineer/v1/app -H "Authorization: Bearer $FLOW_MESSAGING_KEY"
# "livemode": false  -> a test key
```

| | Test mode | Live mode |
| - | - | - |
| Key | `fk_test_...` | `fk_live_...` |
| Senders | The shared sandbox senders | Your dedicated senders |
| Who can be messaged | Only people who sent your app's join code | Anyone the channel's rules allow |
| Data | Test conversations, events, files and webhook endpoints | Live ones |

## Rules

* **Nothing in test mode reaches a real contact** unless that person joined the sandbox through your app. Build and test freely.
* **The modes never mix.** Every object has `livemode`. A test key cannot see live data or use a live sender (`403` [`permission`](/errors/permission)), and webhook endpoints receive only their own mode's events.
* **A key is shown once**, when it is issued, and stored only as a hash. Get a test key with no account in one call (`curl -X POST https://api.flow.engineer/v1/sandbox/keys`, or `npx @flow-engineer/messaging init`); signed in, you make live keys (`fk_live_...`) in the dashboard for your own Telegram bot (iMessage lines are arranged with the Flow team; WhatsApp is not available yet). Signed-in people create and revoke keys in the [dashboard](https://api.flow.engineer/admin); otherwise ask the Flow team to revoke a key if it leaks.
* **Test mode has a sandbox allowance.** Without an account: 1 contact, 50 messages in total, and the key expires after 7 days (`api_key.expires_at`). Signed in with GitHub: 3 contacts, 100 messages each, no expiry, one allowance per person shared by all their apps. It covers the Telegram sandbox (and WhatsApp when its sandbox opens), not iMessage, and counts only messages your agent sends. `GET /v1/app` returns what is left (`allowance`). See [Keys and sign-in](/get-a-key).
* **Keep live keys on your server.** Never ship a key in a web page or a mobile app.

## Going from test to live

Your code does not change. Connect your own Telegram bot (or have the Flow team connect an iMessage line), switch `FLOW_MESSAGING_KEY` to a live key, and register your webhook endpoint again with the live key. See [Going live](/guides/going-live).


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