Saltar al contenido principal

Authentication

Every request to Fyso needs two things: proof of identity and a tenant context. This page covers all authentication methods with working examples.


API Keys (fyso_ak_*)

Created in the admin panel. Grants full owner-level access to the bound tenant. This is what the MCP server uses.

Header:

Authorization: Bearer fyso_ak_...

REST example:

curl -H "Authorization: Bearer fyso_ak_abc123..." \
https://api.fyso.dev/api/entities

MCP setup: Pass the key as the FYSO_API_KEY environment variable:

{
"env": {
"FYSO_API_KEY": "fyso_ak_abc123...",
"FYSO_API_URL": "https://api.fyso.dev/api"
}
}

The key is shown once at creation. Store it securely — it cannot be retrieved again.


Platform API Keys (fyso_pkey_*)

Role-based keys for controlled external access. You define an API with a permission matrix (which entities, which operations, per role), then issue keys for each role.

Header:

Authorization: Bearer fyso_pkey_...

Permissions are enforced per request:

HTTP methodRequired permission
GET /api/entities/:entity/*read
POST /api/entities/:entity/recordscreate
PUT/PATCH /api/entities/:entity/records/:idupdate
DELETE /api/entities/:entity/records/:iddelete

Example: Create an API, issue a key, use it

Step 1 — Define the API:

curl -X POST https://api.fyso.dev/api/apis \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Partner CRM API",
"slug": "partner-crm",
"roles": ["viewer", "editor"],
"permissions": {
"contacts": { "viewer": ["read"], "editor": ["read", "create", "update"] },
"deals": { "viewer": ["read"], "editor": ["read", "create", "update", "delete"] }
}
}'

Step 2 — Issue a key for the viewer role:

curl -X POST https://api.fyso.dev/api/apis/API_ID/keys \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"role": "viewer",
"label": "Partner A read access",
"ttlDays": 365
}'

# Response (key shown only once):
# { "success": true, "data": { "key": "fyso_pkey_abc123...", "role": "viewer", ... } }

Step 3 — Use the key:

# This works (viewer has read on contacts):
curl -H "Authorization: Bearer fyso_pkey_abc123..." \
https://api.fyso.dev/api/entities/contacts/records

# This fails with 403 (viewer can't create):
curl -X POST -H "Authorization: Bearer fyso_pkey_abc123..." \
-H "Content-Type: application/json" \
-d '{"data": {"name": "New Contact"}}' \
https://api.fyso.dev/api/entities/contacts/records

Use "*" as the entity name in the permission matrix to grant access to all entities for a role.

See API Management for full CRUD reference.


Public Keys (fyso_pk_*)

Read-only, rate-limited keys for client-side use. Each key is bound to a role that controls which entities and fields are visible.

Headers (any of these):

X-Public-Key: fyso_pk_...
Authorization: Bearer fyso_pk_...
X-Anon-Key: fyso_pk_... # legacy, still supported

Constraints:

  • Read-only — POST, PUT, DELETE return 401
  • TTL is mandatory (1-365 days, default 90)
  • Per-key rate limits (default: 60/min, 1,000/day)
  • Optional CORS origin allowlist
  • Field exclusions configured on the role (server-side, cannot be bypassed)

Supported scopes: records:read, channels:read

Example: Create a public key

curl -X POST https://api.fyso.dev/api/auth/public-keys \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"label": "Public product catalog",
"roleId": "ROLE_UUID",
"scopes": ["records:read"],
"ttlDays": 180,
"allowedOrigins": ["https://mystore.com"],
"rateLimitPerMin": 120,
"rateLimitPerDay": 10000
}'

# Response (key shown only once):
# { "success": true, "data": { "key": "fyso_pk_abc123...", ... } }

Use the key:

curl -H "X-Public-Key: fyso_pk_abc123..." \
https://api.fyso.dev/api/entities/products/records

See Public Keys for full reference including role permissions and field exclusions.


Bot Identity

For multi-agent systems and service accounts. Bots are registered per tenant, identified by name + secret. The secret is shown once at registration and can be reset.

All bot management endpoints require admin authentication.

Register a bot

curl -X POST https://api.fyso.dev/api/auth/bots/register \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "inventory-agent",
"tenantSlug": "my-workspace"
}'

# Response (201):
# {
# "success": true,
# "data": {
# "id": "uuid",
# "name": "inventory-agent",
# "secret": "a1b2c3...long-random-string",
# "tenantSlug": "my-workspace"
# }
# }

The secret is shown only once. Store it immediately.

Identify (authenticate) a bot

curl -X POST https://api.fyso.dev/api/auth/bots/identify \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "inventory-agent",
"secret": "a1b2c3...long-random-string"
}'

# Response (200):
# {
# "success": true,
# "data": {
# "id": "uuid",
# "name": "inventory-agent",
# "tenantSlug": "my-workspace",
# "tenantId": "uuid"
# }
# }

Other bot endpoints

EndpointMethodDescription
/api/auth/botsGETList all bots in the tenant
/api/auth/bots/:id/revokePOSTRevoke a bot (identify calls will fail)
/api/auth/bots/:id/reset-secretPOSTGenerate a new secret (old one stops working)

MCP tools

ToolDescription
register_botRegister a new bot
identify_botAuthenticate a bot by name + secret
list_botsList bots in the tenant
whoami_botGet current bot identity
revoke_botRevoke a bot

Tenant User Login

For user-facing apps where end users log in with email and password.

Login

curl -X POST https://api.fyso.dev/api/auth/tenant/login \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: my-workspace" \
-d '{
"email": "user@example.com",
"password": "securepassword"
}'

# Response:
# {
# "success": true,
# "data": {
# "token": "eyJhbGci...",
# "user": { "id": "uuid", "email": "user@example.com", "name": "Jane", "role": "member" }
# }
# }

Use the JWT in subsequent requests:

curl -H "Authorization: Bearer eyJhbGci..." \
https://api.fyso.dev/api/entities/contacts/records

Self-service flows

These endpoints don't require admin auth — only the X-Tenant-ID header. They must be enabled in tenant settings.

EndpointDescription
POST /api/auth/tenant/registerSelf-registration (creates viewer role)
POST /api/auth/tenant/forgot-passwordSend password reset email
POST /api/auth/tenant/reset-passwordApply new password with reset token
POST /api/auth/tenant/change-passwordAuthenticated password change

See Users for full details on self-service configuration and rate limits.

MCP tool

tenant_login({ tenantSlug: "my-workspace", email: "user@example.com", password: "securepassword" })

Returns a JWT you can use with the REST API.


Tenant Context

Every operation targets a specific tenant. Fyso resolves the tenant from (in priority order):

MethodHow
X-Tenant-ID headerX-Tenant-ID: my-workspace
X-Tenant-Slug headerX-Tenant-Slug: my-workspace
API key bindingKeys created in a tenant automatically target that tenant
Host-basedSubdomain resolution (for custom domain setups)

MCP: Use select_tenant at the start of a session to set the active tenant. All subsequent tool calls operate on that tenant.

select_tenant({ tenantSlug: "my-workspace" })

If you're using an API key (fyso_ak_*), the tenant is already bound to the key — no header needed. Platform keys (fyso_pkey_*) also carry their tenant binding. For tenant user tokens and public keys, include the tenant header explicitly.