Nitrofy LogoNitrofy
Como funcionaBeneficiosIntegracoesPlanosDuvidas
Comece agora
Nitrofy Logo
Comecar
Introduction
QuickstartEnvironment SetupRunning LocallyFirst Deploy
Organizations & TenancyAuthentication & SessionsRoles & PermissionsControllers & ProceduresJobs & QueuesPlugin ManagerContent LayerBuilt-in MCP ServerBillingNotificationsFile StorageEmailWebhooksAPI KeysSEOData FetchingDesign System
Development

API Keys

Secure programmatic access with organization-scoped API keys, authentication, and management.

By the end of this guide, you'll have set up API keys for secure programmatic access to your organization's resources, with proper authentication, scoping, and management capabilities.

Overview

The SaaS Boilerplate includes a comprehensive API key system that enables secure programmatic access to organization resources without requiring user authentication. Key features include:

  • Organization scoping: API keys are tied to specific organizations with proper data isolation
  • Secure generation: Cryptographically secure keys with 'sk_' prefix for easy identification
  • Flexible expiration: Keys can never expire or have custom expiration dates
  • Enable/disable control: Instantly revoke access by disabling keys
  • Bearer token authentication: Standard HTTP Authorization header authentication
  • Role-based access: API keys inherit organization permissions and require role validation
  • Audit trail: Creation notifications and proper logging for security monitoring
  • One-time display: Keys are shown only once during creation for security

The system integrates deeply with the authentication layer, automatically creating virtual sessions for API key requests while maintaining organization context and billing information.

Architecture

API Key Service

The API key system consists of several integrated components:

// src/@saas-boilerplate/features/api-key/procedures/api-key.procedure.ts
const ApiKeyFeatureProcedure = igniter.procedure({
  handler: async (_, { context }) => ({
    apikey: {
      create: async (input) => {
        // Generate secure key: sk_ + 32 random bytes
        const apiKey = `sk_${crypto.randomBytes(32).toString('hex')}`
        return context.services.database.apiKey.create({ data: { ...input, key: apiKey } })
      },
      findManyByOrganization: async (orgId) => { /* ... */ },
      update: async (params) => { /* ... */ },
      delete: async (params) => { /* ... */ }
    }
  })
})

Authentication Integration

API keys are validated through the authentication procedure, which checks for Bearer tokens when no regular session exists:

// src/@saas-boilerplate/features/auth/procedures/auth.procedure.ts
getSession: async (options) => {
  // Check for API key in Authorization header
  const authHeader = request.headers.get('Authorization')
  if (authHeader?.startsWith('Bearer ')) {
    const token = authHeader.substring(7)
    const apiKey = await context.services.database.apiKey.findUnique({
      where: { key: token, enabled: true },
      include: { organization: true }
    })
    
    if (apiKey) {
      // Create virtual session with organization context
      return { user: null, organization: apiKey.organization }
    }
  }
}

Database Schema

API keys are stored with organization relationships and security metadata:

Prop

Type

Setting Up API Keys

Access API Keys Management

Navigate to your organization's settings and locate the API Keys section. Only organization owners and admins can access this area.

Create Your First API Key

Click "Create API Key" and provide a descriptive name. Choose whether the key should never expire or set a custom expiration date.

Copy and Store the Key

The API key will be displayed only once for security. Copy it immediately and store it securely - it cannot be retrieved later.

Configure Expiration (Optional)

Set an expiration date if you want the key to automatically become invalid, or leave it as "never expires" for permanent access.

Backend Usage (Procedures & Controllers)

Creating API Keys Programmatically

Use the API key procedure to create keys in your business logic. Note that ApiKeyFeatureProcedure must be included in the controller's use array to access context.apikey:

// In a controller or procedure
export const createApiKeyEndpoint = igniter.mutation({
  use: [ApiKeyFeatureProcedure(), AuthFeatureProcedure()],
  handler: async ({ context }) => {
    const session = await context.auth.getSession({
      requirements: 'authenticated',
      roles: ['owner', 'admin']
    })

    const newApiKey = await context.apikey.create({
      description: 'Webhook Integration Key',
      neverExpires: false,
      expiresAt: new Date('2024-12-31'),
      organizationId: session.organization.id
    })

    // Send notification about new key
    await context.services.notification.send({
      type: 'API_KEY_CREATED',
      context: { organizationId: session.organization.id },
      data: {
        description: newApiKey.description,
        keyPreview: newApiKey.key.slice(-4)
      }
    })

    return response.created(newApiKey)
  }
})

API Key Authentication in Controllers

Protect endpoints that should accept API key authentication:

// Controller that accepts both user and API key auth
export const protectedEndpoint = igniter.query({
  use: [AuthFeatureProcedure()],
  handler: async ({ context }) => {
    const session = await context.auth.getSession({
      requirements: 'authenticated',
      roles: ['member', 'admin', 'owner'] // API keys need roles specified
    })
    
    // session.organization is available for both user and API key auth
    // session.user is null for API key authentication
    return { data: session.organization }
  }
})

Managing API Keys

Retrieve and manage keys for an organization. Remember to include ApiKeyFeatureProcedure in your controller's use array:

// In a controller with ApiKeyFeatureProcedure in use array
const apiKeys = await context.apikey.findManyByOrganization(orgId)

// Update key status
await context.apikey.update({
  id: 'key_123',
  description: 'Updated description',
  enabled: false
})

// Delete a key
await context.apikey.delete({
  id: 'key_123',
  organizationId: orgId
})

Frontend Usage (Client-side)

Listing API Keys

Display organization's API keys with management options:

// Get all API keys for the current organization
const result = await api.apiKey.findManyByOrganization.query()

if (result.error) {
  console.error('Failed to load API keys')
} else {
  const apiKeys = result.data
  // Render keys list with masked values
}

Creating New API Keys

Handle API key creation with proper error handling:

const createApiKey = async (description: string, neverExpires: boolean) => {
  try {
    const result = await api.apiKey.create.mutate({
      description,
      neverExpires,
      enabled: true
    })
    
    if (result.error) {
      toast.error('Failed to create API key')
      return
    }
    
    // Show the key only once - copy it immediately
    const newKey = result.data
    navigator.clipboard.writeText(newKey.key)
    toast.success('API key created and copied to clipboard')
    
    // Refresh the list
    router.refresh()
  } catch (error) {
    toast.error('Error creating API key')
  }
}

Updating API Keys

Modify key properties like description or enabled status:

const updateApiKey = async (id: string, updates: { description?: string, enabled?: boolean }) => {
  try {
    await api.apiKey.update.mutate({
      id,
      ...updates
    })
    toast.success('API key updated')
  } catch (error) {
    toast.error('Failed to update API key')
  }
}

Deleting API Keys

Permanently remove API keys with confirmation:

const deleteApiKey = async (id: string) => {
  if (!confirm('Are you sure you want to delete this API key? This action cannot be undone.')) {
    return
  }
  
  try {
    await api.apiKey.delete.mutate({ id })
    toast.success('API key deleted')
    router.refresh()
  } catch (error) {
    toast.error('Failed to delete API key')
  }
}

API Key Authentication

Using API Keys in Requests

Make authenticated requests using Bearer token authentication:

// Example API request with API key
const response = await fetch('/api/protected-endpoint', {
  headers: {
    'Authorization': 'Bearer sk_abc123def456...',
    'Content-Type': 'application/json'
  }
})

API Key Session Context

API keys create virtual sessions with organization context:

// API key authenticated session
const session = await context.auth.getSession({
  requirements: 'authenticated',
  roles: ['member'] // Required for API key auth
})

// Available in API key sessions:
console.log(session.organization) // Full organization object
console.log(session.user) // null (no user for API keys)
console.log(session.organization.billing) // Billing information included

API Key Data Structure

ApiKey Interface

Prop

Type

Troubleshooting

Best Practices

See Also

  • Authentication & Sessions - How API keys integrate with the authentication system
  • Organizations and Tenancy - Organization-scoped API key access
  • Notifications - API key creation notifications
  • Jobs & Queues - Background processing with API key authentication

API Reference

API Key Endpoints

Prop

Type

Authentication Headers

Prop

Type

Webhooks

Subscribe to events and handle incoming webhooks securely.

SEO

Comprehensive SEO setup with metadata, dynamic OG images, sitemaps, structured data, and performance optimization.

On this page

OverviewArchitectureAPI Key ServiceAuthentication IntegrationDatabase SchemaSetting Up API KeysAccess API Keys ManagementCreate Your First API KeyCopy and Store the KeyConfigure Expiration (Optional)Backend Usage (Procedures & Controllers)Creating API Keys ProgrammaticallyAPI Key Authentication in ControllersManaging API KeysFrontend Usage (Client-side)Listing API KeysCreating New API KeysUpdating API KeysDeleting API KeysAPI Key AuthenticationUsing API Keys in RequestsAPI Key Session ContextAPI Key Data StructureApiKey InterfaceTroubleshootingBest PracticesSee AlsoAPI ReferenceAPI Key EndpointsAuthentication Headers
Nitrofy LogoNitrofy

Automatize o envio e a cobrança dos seus contratos

© 2026 Nitrofy, All rights reserved