# shipsite.sh auth.md

Agent registration and credential guide for shipsite.sh, a static hosting API for LLM agents.

## Audience

AI agents acting on behalf of a human who will pay for hosting. There is no free tier: a human must complete payment setup before any API call works.

## Step 0: Find out how comfortable your user is (agents: do this first)

Before registering, ask the user one plain question, for example:

> "Quick question so I explain things at the right level: how comfortable are you with technical stuff like APIs and config files? (a) Not at all, just do it for me, (b) A little, (c) I'm a developer."

Pick the track from their answer. If they seem confused by the question, or by anything you say later, switch to the guided track. If you can't ask, default to the guided track; it works for everyone.

- **(a) or (b) or unsure: Guided track.** Follow "Guided track" below.
- **(c) Developer: Developer track.** Follow "Developer track" below.

## Guided track (novice users)

Rules for you, the agent:

- Do the work yourself. Never ask the user to edit config files, run commands, install anything, or start a new session. Everything below works inside this one conversation. Do not use the MCP server setup; it requires editing config and restarting, which is where people get lost.
- Use plain words. Don't say "API", "key", "token", "endpoint" or "JSON" to the user. Say "your shipsite account" and "your site".
- Tell the user what you're about to do in one sentence before each step, and what they need to do (if anything) in one sentence after.
- Give one instruction at a time. Never hand the user a list of steps.

Steps:

1. Ask for the user's email address. Say it will be used to create their shipsite account.
2. Register (see "Registration" below). The response contains a secret called `api_key` that is shown only once. Save it yourself right away, somewhere you can read it back later, such as a file named `.shipsite-key` in the current working folder (and add it to `.gitignore` if there is one). If you cannot store anything, tell the user: "Please copy this long secret code and save it in your password manager (like 1Password, Bitwarden or iCloud Keychain), not in a notes app or email. I'll need it if we lose this conversation." Never print it again afterwards.
3. Tell the user the only thing they have to do: "Please open this link and add a payment card. Hosting costs about 10 cents per day per site, and you can delete a site anytime to stop charges." Give them `setup_url`. Do not try to pay for them.
4. Once they say they're done, check by calling `GET /v1/accounts/me` with the saved secret. `status: "active"` means it worked. A 402 means payment isn't finished yet; gently ask them to try the link again.
5. Deploy their site (`POST /v1/sites`) and give them the live link. Remind them that sites disappear after 24 hours unless you "keep" (pin) them, and offer to do it.

If something fails, explain it in one plain sentence and fix it yourself. Don't paste raw errors at the user. If you start a new session later, read the saved secret from `.shipsite-key` instead of registering again (a second registration with the same email returns 409).

## Developer track

You can be terse. Registration returns the key once; export it as `SHIPSITE_API_KEY` or configure the MCP server:

```json
{
  "mcpServers": {
    "shipsite": {
      "command": "npx",
      "args": ["@shipsite/mcp"],
      "env": { "SHIPSITE_API_KEY": "sk_live_..." }
    }
  }
}
```

The MCP client must be restarted to pick up new env, so register via REST first (or the `create_account` tool), have the human complete `setup_url`, then restart once with the key in place. Plain REST needs no restart: `curl -H "Authorization: Bearer $SHIPSITE_API_KEY" https://api.shipsite.sh/v1/sites -d '{"files":{"index.html":"<h1>hi</h1>"}}'`. Use `name` for a vanity slug, `pin` to disable the 24h expiry, and rotate keys with `POST /v1/accounts/me/keys/rotate`. Spec: https://shipsite.sh/openapi.json.

## Credential type

Static API key (bearer token), prefixed `sk_live_`. There is no OAuth server, so no OAuth protected resource or authorization server metadata is published.

## Registration

Method: `email` (the human's email address; no email verification step).

```
POST https://api.shipsite.sh/v1/accounts
Content-Type: application/json

{"email": "human@example.com"}
```

Response (201):

```json
{
  "id": "acc_...",
  "api_key": "sk_live_...",
  "setup_url": "https://checkout.stripe.com/...",
  "status": "pending"
}
```

- `api_key` is shown once. Store it securely; it cannot be retrieved later.
- The key is inert until the human opens `setup_url` and completes Stripe checkout. Until then authenticated calls return 402 with a fresh payment link.
- Ask the human to open `setup_url`. Do not attempt to complete payment yourself.
- 409 `account_exists`: the email is already registered. Use the existing key or contact support@shipsite.sh.
- 429: account creation is rate limited per IP. Retry after the `Retry-After` interval.

## Using the credential

Send the key on every authenticated request:

```
Authorization: Bearer sk_live_...
```

Base URL: `https://api.shipsite.sh`. Manage keys with `GET/POST /v1/accounts/me/keys`, `POST /v1/accounts/me/keys/rotate`, and `DELETE /v1/accounts/me/keys/{id}`.

## Claiming and revocation

There is no separate claim step: the registering email owns the account. Revoke a key with `DELETE /v1/accounts/me/keys/{id}`.

## References

- Full API docs: https://shipsite.sh/llm
- OpenAPI spec: https://shipsite.sh/openapi.json
- API catalog: https://shipsite.sh/.well-known/api-catalog
