DEV Community

Alex Spinov
Alex Spinov

Posted on

Zitadel Has a Free API — Heres How to Build Multi-Tenant Auth in Minutes

Zitadel is an open-source identity platform with multi-tenancy built in. Perfect for SaaS — each customer gets their own organization with separate users, roles, and branding.

Why Zitadel?

  • Multi-tenant by default: Each org has isolated users
  • OIDC/OAuth2/SAML: Industry standards
  • Passwordless: WebAuthn, passkeys
  • Actions: Custom logic on auth events (like Auth0 Actions)
  • Self-hosted or cloud: Both options
  • gRPC + REST: Both API styles
  • Free tier: 25K MAUs on cloud

Self-Host

docker run -p 8080:8080 \
  ghcr.io/zitadel/zitadel:latest start-from-init \
  --masterkey "MasterkeyNeedsToHave32Characters" \
  --tlsMode disabled
Enter fullscreen mode Exit fullscreen mode

Console at http://localhost:8080

API: Create Organization

curl -X POST http://localhost:8080/management/v1/orgs \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"name": "Acme Corp"}'
Enter fullscreen mode Exit fullscreen mode

API: Create User

curl -X POST http://localhost:8080/management/v1/users/human/_import \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "userName": "alice@acme.com",
    "profile": {"firstName": "Alice", "lastName": "Smith"},
    "email": {"email": "alice@acme.com", "isEmailVerified": true},
    "password": "SecureP@ssw0rd!"
  }'
Enter fullscreen mode Exit fullscreen mode

API: Create Project + App

# Create project
curl -X POST http://localhost:8080/management/v1/projects \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -d '{"name": "My SaaS"}'

# Create OIDC app
curl -X POST http://localhost:8080/management/v1/projects/PROJECT_ID/apps/oidc \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -d '{
    "name": "Web App",
    "redirectUris": ["http://localhost:3000/callback"],
    "responseTypes": ["OIDC_RESPONSE_TYPE_CODE"],
    "grantTypes": ["OIDC_GRANT_TYPE_AUTHORIZATION_CODE"],
    "appType": "OIDC_APP_TYPE_WEB"
  }'
Enter fullscreen mode Exit fullscreen mode

React Integration

import { ZitadelAuth } from '@zitadel/react';

const config = {
  authority: 'http://localhost:8080',
  client_id: 'YOUR_CLIENT_ID',
  redirect_uri: 'http://localhost:3000/callback',
  scope: 'openid profile email',
};

function App() {
  return (
    <ZitadelAuth config={config}>
      <ProtectedContent />
    </ZitadelAuth>
  );
}
Enter fullscreen mode Exit fullscreen mode

Actions (Custom Logic)

// Run on pre-creation
function preCreation(ctx, api) {
  // Auto-assign role based on email domain
  if (ctx.user.email.endsWith('@acme.com')) {
    api.setMetadata('role', 'employee');
  }
}
Enter fullscreen mode Exit fullscreen mode

Real-World Use Case

A B2B SaaS needed separate user pools per customer, with each customer managing their own users. Zitadel's multi-tenancy meant zero custom code — each customer is an organization with its own users, roles, and even login branding. What would take 2 months to build took 2 days.


Need to automate data collection? Check out my Apify actors for ready-made scrapers, or email spinov001@gmail.com for custom solutions.

Top comments (0)