Docs

Orgs: run Unbrowse for your own users

For teams that build agents for other people: agencies, forward-deployed engineers, and products with an AI assistant. You hold one account, one key and one bill. Each of your users gets their own logins and sessions, and a site one of them teaches Unbrowse works for all of them.

Console: unbrowse.ai/app/org.

How it works

YouUnbrowse
Create an org (name, the app name your users see, optional company domain)Makes you the owner; teammates who sign in with that domain join
Mint an org key and put it on your serverStores only its hash; shows it once
Send each call with the org key and X-Unbrowse-End-User: <your user's id>Runs it in that user's own workspace, created on first use, the same one every time
Forward a sign-in link to the right user when a site needs their loginShows "Your App wants to use your site account", seals the login in that user's workspace, then the link stops working
Top up onceCharges every user's verified calls to the org: free allowance first, then paid credits

Your users never create an Unbrowse account. You never handle their passwords, and neither does your model.

1. Create the org and a key

Sign in at https://unbrowse.ai/app/org, create the org, then press Mint org key. Or over REST, signed in or with a personal key:

curl -X POST https://unbrowse.ai/api/v1/org \
  -H "Authorization: Bearer $PERSONAL_KEY" -H "content-type: application/json" \
  -d '{"name": "Acme", "appName": "Acme Assistant", "domain": "acme.com"}'

curl -X POST https://unbrowse.ai/api/v1/org/keys -H "Authorization: Bearer $PERSONAL_KEY"
# → { "id": "key_…", "prefix": "ub_live_…", "token": "ub_live_…" }   (shown once)

2. Call as your user

MCP (Streamable HTTP):

{
  "mcpServers": {
    "unbrowse": {
      "url": "https://unbrowse.ai/mcp",
      "headers": {
        "Authorization": "Bearer ub_live_…",
        "X-Unbrowse-End-User": "user_8421"
      }
    }
  }
}

REST:

curl https://unbrowse.ai/api/v1/runs \
  -H "Authorization: Bearer $ORG_KEY" \
  -H "X-Unbrowse-End-User: user_8421" \
  -H "content-type: application/json" \
  -d '{"task": "my open pull requests on github", "idempotencyKey": "pr-1"}'

Clients that cannot send headers (some hosted MCP clients): mint a key for one user and put it in that user's config.

curl -X POST https://unbrowse.ai/api/v1/org/users \
  -H "Authorization: Bearer $ORG_KEY" -H "content-type: application/json" -d '{"user": "user_8421"}'
# → { "workspaceId": "ws_…", "user": "user_8421", "token": "ub_live_…" }

A per-user key only ever acts as that user. It cannot select another user with the header.

3. When a site needs your user's login

A run refused for sign-in, where the user has no saved login for that site, returns a link instead of guessing:

{ "status": "failed",
  "error": { "code": "session_or_permission", "message": "…" },
  "signIn": { "url": "https://unbrowse.ai/connect/cr_…", "requestId": "cr_…", "origin": "https://github.com",
              "message": "…" } }

(mfa_required is the other code that carries signIn.)

unbrowse_credentials_request {origin, reason} creates one on demand; unbrowse_credentials_status {requestId} reports pending, fulfilled, declined or expired.

Send the link to that user (chat, email, in-app). The page says "Acme Assistant wants to use your github.com account" with the reason. They sign in there, or press Don't connect. Once unbrowse_credentials_status says fulfilled, call again with the same input.

4. One bill

5. Tools your users share

When one of your users runs a site Unbrowse had to learn, the route is shared with your other users, so their first call is fast too:

REST reference

MethodPathCallerDoes
POST/api/v1/org {name, appName?, domain?}signed-in personcreate; you become owner (one org per person)
GET/api/v1/orgmember or org keyorg, members, users (calls, connected sites), shared tools, keys, balance
POST/api/v1/org/keysmembermint an org key (403 for an org key)
POST/api/v1/org/keys/revoke {id}member or org keyrevoke an org or per-user key of this org
POST/api/v1/org/users {user}member or org keykey for one user
POST/api/v1/org/settings {sharePublic}memberpublic sharing of org tools
GET/api/v1/connect/:idanyone with the linkapp name, site, reason, status
POST/api/v1/connect/:id {username?, email?, password, totp?}anyone with the linksave the login once
POST/api/v1/connect/:id/declineanyone with the linkdecline

Every other endpoint (/runs, /sites/..., /usage, MCP tools) takes the org key plus X-Unbrowse-End-User.

Errors

StatusCodeMeaning
401unauthorizedmissing, wrong or revoked key
403forbiddenX-Unbrowse-End-User with a key that is not an org key; an org key minting keys or changing settings
404no_orgyou are not in an org yet
409already_member / domain_taken / request_closedone org per person; domain claimed; connect link used, declined or expired
422invalid_requestmalformed user id, bad or free-mail domain, missing password
402quota_exceededthe org's free and paid credits are both empty

Not yet

Leaving an org, removing a member, transferring ownership, per-user spending caps, custom domains, and hiding the Unbrowse name. The connect page says "secured by Unbrowse".