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

# Sella authentication: OTP, API keys, and multi-chain wallets

> Authenticate your agent once with an email OTP, get an API key and non-custodial multi-chain wallets. Keys stay local — Sella never holds private keys.

Sella authenticates an agent once, then lets it transact autonomously from that point forward. The authentication flow is human-driven and one-time: a human reads a six-digit code from their inbox and hands it to the agent. Everything after that — discovery, evaluation, purchasing, and payment signing — is handled entirely by the agent without any further human involvement.

## The two-step OTP flow

Authentication uses two MCP tools that any agent can call without a key already in place — making it possible for a fresh agent to bootstrap its own credentials.

<Steps>
  <Step title="sella_auth_start" icon="mail">
    Call `sella_auth_start` with the operator's email address. Sella sends a 6-digit one-time code to that address. The code expires in 10 minutes.

    ```json theme={null}
    { "name": "sella_auth_start", "arguments": { "email": "you@example.com" } }
    ```
  </Step>

  <Step title="sella_auth_complete" icon="check">
    The human reads the code from their inbox and passes it to the agent, which calls `sella_auth_complete`:

    ```json theme={null}
    { "name": "sella_auth_complete", "arguments": { "email": "you@example.com", "otp_code": "123456" } }
    ```

    On success, Sella returns your API key, your agent ID, and — on first login — your wallet private keys.
  </Step>

  <Step title="Save credentials" icon="download">
    <Warning>
      Private keys are shown **exactly once**, at first onboard. Save `walletConfig` to `~/.sella-wallet.json` immediately, then add `apiKey` to your MCP config. If you lose this file, you keep the same public addresses but cannot recover the private keys.
    </Warning>
  </Step>
</Steps>

## What you get back

The full response from a successful `sella_auth_complete` call looks like this:

```json theme={null}
{
  "status": "onboarded",
  "agentId": "agt_xxxxxxxxxxxxxxxx",
  "apiKey": "sk_live_your_32_char_key_shown_here",
  "mcpServerUrl": "https://sellag.vercel.app/api/mcp",
  "walletConfig": { "stellar": { }, "solana": { }, "base": { } },
  "instructions": "Save walletConfig to ~/.sella-wallet.json immediately — private keys are shown only once."
}
```

<ResponseField name="apiKey" type="string">
  Your bearer token, prefixed `sk_live_`. Pass this as `Authorization: Bearer sk_live_…` in every MCP request. A **fresh key is minted on every successful auth** — the previous key stops working, so update your MCP config each time you re-authenticate.
</ResponseField>

<ResponseField name="agentId" type="string">
  A stable identifier for your agent, prefixed `agt_`. This does not change between re-authentications.
</ResponseField>

<ResponseField name="walletConfig" type="object">
  Private keys for your non-custodial wallets. Returned **only on first onboard** (status `onboarded`). Save this to `~/.sella-wallet.json` immediately — it will not be shown again.
</ResponseField>

<ResponseField name="walletAddresses" type="object">
  Returned on re-authentication (status `reauthed`) instead of `walletConfig`. Contains your public addresses only — your private keys already live in `~/.sella-wallet.json` from the first onboard.
</ResponseField>

## Key lifecycle

Every successful call to `sella_auth_complete` mints a brand-new `sk_live_` API key and invalidates the previous one. This is by design: re-authentication is the mechanism for rotating a compromised key. After any re-auth, update `SELLA_API_KEY` in your MCP config before making further calls — stale keys return `401`.

## Non-custodial by design

Your agent runs on your machine. Sella is the marketplace and settlement layer, not the execution environment.

<CardGroup cols={2}>
  <Card title="Keys stay local" icon="lock" href="/consumers/operators">
    `~/.sella-wallet.json` lives on your machine. Sella stores only your public addresses and cannot sign on your behalf.
  </Card>

  <Card title="You sign every payment" icon="pen-tool" href="/reference/x402">
    Each x402 payment is signed locally by your agent using a per-payment nonce and expiry. Nothing is co-signed or custodied.
  </Card>
</CardGroup>

## Multi-chain wallets

Onboarding provisions wallets across multiple chains so your agent can settle wherever a product requires it. The [x402](/reference/x402) challenge your agent receives always specifies the exact chain and amount — your agent just signs and pays.

| Chain           | Status  | Typical use                             |
| --------------- | ------- | --------------------------------------- |
| Base            | Live    | EVM settlement, larger purchases        |
| Solana          | Live    | High-frequency micropayments            |
| Stellar         | Live    | Low-fee dataset purchases               |
| Ethereum, Tempo | Preview | Added for the API Data Market wallet    |
| Sui, Aptos      | Planned | Rolling out with the multi-chain router |

<Note>
  The API Data Market uses a **separate** wallet at `~/.sella-agentwallet/config.json`, tuned for pay-per-call API proxying. Your core `~/.sella-wallet.json` covers datasets, Cradle compute, and Mergekit jobs. See [API Data Market](/consumers/api-market) for details.
</Note>

## Re-authenticating

Run the same two-step flow again at any time to rotate your key or recover after a config wipe. Calling `sella_auth_complete` for an existing operator returns `status: "reauthed"` with a new API key and your existing public wallet addresses. Swap the new key into your MCP config and you're back up immediately.

<Accordion title="What happens to my wallets if I re-authenticate?">
  Nothing. Re-authentication rotates your API key only. Your wallet private keys in `~/.sella-wallet.json` are unchanged, your public addresses stay the same, and any balance you've funded is still there. Only the `sk_live_` bearer token changes.
</Accordion>

## Next steps

<CardGroup cols={2}>
  <Card title="Operating agents" icon="sliders" href="/consumers/operators">
    Fund wallets, set spend budgets, and govern agent behaviour with SKILLS.md.
  </Card>

  <Card title="x402 payments" icon="coins" href="/reference/x402">
    The protocol behind every paid call — how challenges, signatures, and settlement work.
  </Card>
</CardGroup>
