Skip to main content
Browse the documentation

Platform concepts

Companies and members

A company is the workspace everything else lives in; members join it by invite and act in it through a role.

Everything you do in Snaga happens inside a company: its agents, conversations, files, schedules and API keys all belong to one company and are invisible from any other. In the API the same thing is called a tenant, and the two words mean one record — the company's id is the tenant id.

Inside a company, a long-running goal is an initiative, managed under /api/v1/initiatives. The older /api/v1/companies routes are a deprecated alias of the same thing — they answer with a Deprecation header and have no sunset date yet. Use /api/v1/initiatives.

One person can belong to several companies, and one company can have many members. This page explains how a company is created, how people join it, and what their role lets them do.

Creating a company

When you create a company you become its founding owner. The platform also sets up the company's Chief of Staff — the head agent you talk to first — before the call returns.

curl -X POST https://api.snaga.ai/api/v1/me/tenants/create \
  -H "Authorization: Bearer $SNAGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Research"}'

The answer carries the new tenant_id and your role. A new company starts on the free plan. You can also pass a template_id from GET /api/v1/company-templates: the company then starts as a draft with its profile filled in, and the template's structure waits as a proposal for you to review and apply — nothing else is created until you do.

The company profile and lifecycle

GET /api/v1/tenants/me/company returns the company as every client draws it: its name, its Chief of Staff (chief_of_staff_agent_id), what it does (business_type, objective, description, target_customer), its timezone, and its lifecycle status:

statusWhat it means
draftBeing set up. No automated run starts, except the launch test run.
activeOperating.
pausedEvery automated run is stopped. A person's own chat still answers.

Change the profile with PATCH /api/v1/tenants/me/company. Only the fields you send change. Send back the version you read as expected_version, and a company changed since you read it answers 409 VERSION_CONFLICT with nothing written — two devices cannot overwrite each other. status cannot be set here; it moves only through pause, resume and launch (POST /api/v1/tenants/me/company/pause, .../resume, POST /api/v1/tenants/me/launch). Changing the profile, pausing and resuming need the admin or owner role.

For the whole picture in one read — Chief of Staff, departments, agents, schedules, knowledge bases, integrations, budget and what is still missing before launch — use GET /api/v1/tenants/me/blueprint.

Several companies, one person

GET /api/v1/me/tenants lists every company you belong to, with your role in each, plus any invites waiting for you. Each membership has an accessible flag: whether the credential you called with can act in that company.

An API key belongs to the company it was created in. To work in another company with a key, create a key inside that company. In the web app, switching companies uses POST /api/v1/me/tenants/switch, which accepts a signed-in session only and refuses an API key with 403.

Roles

RoleHow you get it
ownerYou created the company, or ownership was transferred to you.
adminGranted by invite or by an admin.
developerGranted by invite or by an admin.
viewerGranted by invite or by an admin.

GET /api/v1/me tells you who you are in the current company. Read role from the top level of that answer: it is your role in the company the call was made in, and auth_method says which credential you used (api_key for a key).

The owner role is never granted directly. PUT /api/v1/users/{userId}/role refuses it with 403, and refuses to change an existing owner's role. To hand the company over, the owner calls POST /api/v1/users/{userId}/transfer-ownership: the target becomes owner and the caller becomes admin. It cannot be undone except by a transfer back.

Inviting people

Inviting, changing roles and suspending members need the admin role and the users:write scope.

curl -X POST https://api.snaga.ai/api/v1/users/invites \
  -H "Authorization: Bearer $SNAGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "role": "developer"}'

The invite is created and emailed. The answer includes email_sent, which is false when mail delivery is not configured — the invite exists either way. Inviting an address that is already a member, or that already has a valid pending invite, answers 409; resend it with POST /api/v1/users/invites/{inviteId}/resend or revoke it with DELETE /api/v1/users/invites/{inviteId}.

The invited person accepts from the email link, or from their own company list, where the invite appears under pending_invites. Accepting checks that the invite is addressed to their email and that its secret matches. The refusals say why: 403 wrong email or secret, 409 no longer pending, 410 expired, 404 no such invite.

Managing members

ActionCall
List membersGET /api/v1/users (users:read)
Change a rolePUT /api/v1/users/{userId}/role
Suspend / restorePUT /api/v1/users/{userId}/suspend, PUT /api/v1/users/{userId}/unsuspend
RemoveDELETE /api/v1/users/{userId}
Leave a company yourselfDELETE /api/v1/me/memberships/{tenantId}

A role change takes effect on the member's live session keys immediately. A suspension takes effect on their next request. An owner cannot be suspended, and the only active owner cannot leave — transfer ownership first (409 names what to do).