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

# Direct API access

> When an app has no integration or MCP server, Swan can call its API directly — you store the key as a secret, Swan writes and runs the code, and saves what works as a reusable skill.

Some systems have no Swan [catalog integration](built-in-integrations) and no [MCP server](custom-mcp-servers) to connect. For those, there's a third route: Swan calls the system's API directly. You store the API key as a **secret**, then ask Swan — in chat or in a trigger — to work with that API. Swan reads the API's documentation, writes the code, runs it in its code sandbox, and can save the working integration as a skill so it never has to figure it out twice.

This is the fallback, not the default — catalog integrations and MCP servers handle authentication and data schemas for you, so check those first. But it means "there's no integration" is rarely a dead end.

## Secrets

A secret is a named credential — an API key, token, or connection string — stored in Swan:

* **Org secrets** are usable by every user and trigger in the org.
* **Personal secrets** are usable only by you. A personal secret with the same name as an org secret overrides it for your runs.

Manage them at [Settings → Secrets](https://agent.getswan.com/settings/secrets). Values are encrypted at rest, and the agent can never read them back: it sees only secret *names* (plus scope and when each was last used). In code, Swan references a secret as a placeholder — `${secret.STRIPE_API_KEY}` — and the real value is injected only at execution time, inside the sandbox. It never appears in the conversation, and code that would leak a resolved value into an output file is blocked automatically.

One rule on your side: **don't paste keys into chat.** If you do, Swan is instructed to have you add the key at Settings → Secrets instead and delete the message — a value pasted in chat lives in the conversation history; a secret doesn't.

## How Swan works with an API

Ask for what you want in plain language — "pull our open invoices from our billing system, the key is stored as `BILLING_API_KEY`". Swan then works the way a careful engineer would:

1. **Reads the docs first.** It researches the official API reference for the exact endpoints it needs — auth format, parameters, pagination, rate limits — rather than guessing from memory.
2. **Validates step by step.** First a cheap authenticated check, then a single read, then — only if the task requires writing — a single write, confirming with you before the first write to a production system. Only then does it scale up to the full job.
3. **Handles failures diagnosably.** Non-success responses are surfaced with their status and cause, so a bad key, a permissions gap, or a wrong endpoint gets fixed rather than retried blindly.

Each code run costs 1 credit — see [credit costs](../reference/credit-costs).

## Swan remembers what works

Once an integration works, Swan documents it as an org [skill](../knowledge-and-skills/skills) — which secret name to use, the auth format, the endpoints and parameters that mattered, and any gotchas — so the next run, a trigger, or a teammate reuses the working recipe instead of rediscovering it. If you'll use the API regularly, this is what makes it dependable: the first run is exploration, every run after is routine.

## Common questions

**Can Swan see or accidentally reveal my API key?**
No. The agent only ever sees secret names. Values are injected into code at execution time inside the sandbox, are never echoed back, and output that would contain a resolved value is blocked.

**Can a trigger use a secret?**
Yes — org secrets are available to triggers, so a standing automation can call your API on every run. Personal secrets are only available in your own runs.

**What happens if Swan references a secret that doesn't exist?**
The run fails with the missing secret's name, and Swan asks you to add exactly that name at Settings → Secrets, then retries.

**How do I rotate a key?**
Update the secret's value at Settings → Secrets — the name stays the same, so nothing that references it needs to change.

**Should I use this instead of a catalog integration?**
No — if the app is in the [catalog](built-in-integrations) or has an MCP server, use that; auth and schemas are handled for you. Direct API access is for everything else.
