# Sofya: sign-up and payment for agents

Sofya is a web search, fetch, extract and research API for AI agents (https://sofya.co). This file tells an agent how to get an API key and how to get credits, with a person approving both.

## Get an API key (service_auth)

A person approves every key. You start the request, show them a code, and poll until they approve.

1. Start:

```
POST https://sofya.co/v1/agent/signup
Content-Type: application/json

{"client_name": "Your agent's name", "login_hint": "user@example.com"}
```

Both fields are optional. `client_name` is shown to the person. `login_hint` is the email you expect them to use. The response has `claim_token`, `user_code`, `verification_uri`, `verification_uri_complete`, `expires_in` and `interval`. The same values are also nested under `claim`, as in auth.md.

2. Ask your user to open `verification_uri_complete` (it looks like `https://sofya.co/device?code=BCDF-GHJK`), sign in or create an account, check that the code matches, and approve. The code expires in 15 minutes.

3. Poll every 5 seconds:

```
POST https://sofya.co/v1/agent/token
Content-Type: application/json

{"claim_token": "clm_..."}
```

The poll returns `400 {"error": "authorization_pending"}` until they approve. `slow_down` means poll less often. `access_denied` means they said no. `expired_token` means start again. On approval you get `200` with `api_key`, also returned as `access_token`, and the claim is spent. Save the key right away; this is the only time it is returned to you.

The same poll also works as an OAuth token request: `POST https://sofya.co/oauth/token` (form-encoded) with `grant_type=urn:workos:agent-auth:grant-type:claim&claim_token=...`, or with `grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=...`.

Use the key as `Authorization: Bearer <key>` on the REST API and on MCP at `https://mcp.sofya.co/mcp`. It does not expire. The person can set a monthly limit on it or revoke it in their dashboard. You cannot change your own limit.

## Credits

New accounts may start with 0 credits. Every request costs credits (see https://sofya.co/pricing), and only successful requests are charged.

- `GET https://sofya.co/v1/billing/balance` returns `credits`, and this key's `key_monthly_cap` and `key_credits_used_this_month`.
- `POST https://sofya.co/v1/billing/topup` with `{"amount_usd": 10}` returns a `checkout_url`. Give it to your user. They pay on a Stripe page, and the credits are added as soon as the payment goes through. Nothing is charged until they pay. The amount is whole US dollars, from 10 to 25,000. One dollar buys 400 credits.
- On MCP, the same two actions are the `get_balance` and `buy_credits` tools.
- When the account runs out, the API answers `402` with `"error": "insufficient_credits"`, plus `credits_required`, `credits_available` and a `top_up_url` to show your user. `"error": "key_cap_reached"` means this key hit the monthly limit its owner set. Buying credits won't help with that; ask the owner to raise the limit.

## Scope

A key from this flow can call search, fetch, extract and research, read the balance, and make payment links. It cannot pay, change limits, create other keys or change the account.

## More

- Docs: https://sofya.co/docs (markdown: https://sofya.co/docs.md)
- Agent guide: https://sofya.co/skill.md
- OAuth metadata: https://sofya.co/.well-known/oauth-authorization-server and https://sofya.co/.well-known/oauth-protected-resource
- Terms: https://sofya.co/terms. Privacy: https://sofya.co/privacy
- Contact: support@sofya.co