# Authentication

> Page: https://docs.flung.dev/authentication. Index of every page: https://docs.flung.dev/llms.txt

Every call to the Flung API carries one credential in the `Authorization` header. There are three kinds, for three places a call can come from.

## TL;DR

| Credential | Looks like | Use it from | Can do |
|---|---|---|---|
| API key | `flung_sk_...` | Your server | Everything in its workspace |
| OAuth access token | An opaque token | An app or agent a person approved | Everything the person may do in the workspace they chose |
| Connect token | `flung_ct_...` | A web page | Only list, connect, reconnect and disconnect accounts, from the origins it was made for |

Send any of them as `Authorization: Bearer <credential>`.

## API keys

An API key belongs to a workspace, not a person. Keep it on a server, in an environment variable, and never in code a browser loads, a repository or a log. A full-access key can create and revoke keys with the [API keys endpoints](https://docs.flung.dev/reference/api.md#api-keys); to rotate one, create the new key, deploy it, then revoke the old one.

## OAuth for apps and agents

An app or an AI agent can connect to Flung the way apps connect to Google: a person signs in with a link sent to their email, picks the workspace, and approves. The app gets an access token that lasts an hour and a refresh token that lasts 90 days. Flung's authorization server describes itself at `https://api.flung.dev/.well-known/oauth-authorization-server`, and MCP clients find it by themselves. Access stops at once if the person is removed from the workspace.

## Connect tokens for web pages

A page must never hold an API key, so your server makes a connect token for it. The token lasts an hour by default (one minute to one day), works only from the origins you list (https, or `http://localhost` for trying it out), and reaches only the calls a connect panel needs. Give it a `profileId` to keep each of your users to their own accounts, and `platforms` to offer only some.

**curl**

```bash
curl -X POST 'https://api.flung.dev/v1/connect-tokens' \
  --header "Authorization: Bearer $FLUNG_API_KEY" \
  --header 'Content-Type: application/json' \
  --header "Idempotency-Key: $(uuidgen)" \
  --data '{
  "origins": [
    "https://app.example.com"
  ],
  "platforms": [
    "x",
    "linkedin",
    "bluesky"
  ]
}'
```

**TypeScript**

```ts
import { Flung } from '@flung.dev/sdk'

const flung = new Flung({ apiKey: process.env.FLUNG_API_KEY! })
const result = await flung.connectTokens.create({
  origins: [
    'https://app.example.com',
  ],
  platforms: [
    'x',
    'linkedin',
    'bluesky',
  ],
})
```

**fetch**

```js
const response = await fetch('https://api.flung.dev/v1/connect-tokens', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.FLUNG_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({
    origins: [
      'https://app.example.com',
    ],
    platforms: [
      'x',
      'linkedin',
      'bluesky',
    ],
  }),
})
if (!response.ok) throw new Error((await response.json()).error.message)
const result = await response.json()
```

Hand the `token` to the page. [Add account connecting to your site](https://docs.flung.dev/connect-accounts.md) shows the whole flow.

## Where things live

| Service | Address |
|---|---|
| REST API | `https://api.flung.dev` |
| REST API, preview | `https://api-preview.flung.dev` |
| MCP server | `https://mcp.flung.dev` |
| Brand files | `https://assets.flung.dev` |
| These docs | `https://docs.flung.dev` |
