Skip to main content

Overview

OptiFlow uses Laravel Sanctum for API token authentication. This provides a simple, secure way to authenticate API requests without the complexity of OAuth.
All API endpoints require authentication except for public endpoints like health checks. Unauthenticated requests will receive a 401 Unauthorized response.

Authentication Flow

  1. Obtain an API token from your account settings or via the token generation endpoint
  2. Include the token in the Authorization header of every request
  3. Workspace context is automatically set based on your user’s current workspace

Obtaining API Tokens

Via Dashboard

The simplest way to obtain an API token:
  1. Log in to your OptiFlow account
  2. Navigate to Settings > API Tokens
  3. Click Create New Token
  4. Give your token a descriptive name
  5. Copy the token immediately (it won’t be shown again)

Via API (Programmatic)

You can also generate tokens programmatically after authenticating:
use App\Models\User;

$user = User::find(1);
$token = $user->createToken('api-token')->plainTextToken;
Store API tokens securely. They provide full access to your account and should be treated like passwords. Never commit tokens to version control or expose them in client-side code.

Including Tokens in Requests

Include your API token in the Authorization header using the Bearer scheme:
Authorization: Bearer YOUR_API_TOKEN

Example Requests

curl -X GET https://acme.yourdomain.com/api/v1/invoices \
  -H "Authorization: Bearer 1|a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json"

Token Permissions and Scopes

API tokens inherit the permissions of the user who created them. OptiFlow uses Laravel’s Spatie Permission package for fine-grained access control.

Permission Examples

PermissionDescription
invoices:viewView invoices
invoices:createCreate new invoices
invoices:editUpdate existing invoices
invoices:deleteDelete invoices
products:viewView products
products:createCreate products
contacts:viewView contacts
view_all_locationsAccess resources across all workspaces
API requests will fail with 403 Forbidden if the authenticated user lacks the required permission for the requested operation.

Workspace Context

Many API operations require a workspace context. OptiFlow automatically uses the authenticated user’s current workspace, but you can specify a different workspace for multi-workspace operations.

Setting Workspace Context

Include the X-Workspace-ID header to specify which workspace the request should operate in:
curl -X GET https://acme.yourdomain.com/api/v1/products \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Workspace-ID: 3" \
  -H "Accept: application/json"
You can only access workspaces you’re a member of. Attempting to access unauthorized workspaces will return 403 Forbidden.

Default Workspace Behavior

If no X-Workspace-ID is provided:
  1. The system uses your user’s current_workspace_id
  2. If no current workspace is set, the first workspace you belong to is used
  3. If you don’t belong to any workspace, workspace-scoped requests will fail

Token Management

Revoking Tokens

Revoke a token when it’s no longer needed:
// Revoke current token
$request->user()->currentAccessToken()->delete();

// Revoke all tokens
$request->user()->tokens()->delete();

// Revoke specific token
$token = $user->tokens()->where('name', 'api-token')->first();
$token->delete();

Token Expiration

By default, Sanctum tokens do not expire. For enhanced security, you can configure token expiration in config/sanctum.php:
'expiration' => 60 * 24 * 30, // 30 days

Multi-Tenant Authentication

Authentication is tenant-specific. A token generated in one tenant (subdomain) cannot be used to access resources in another tenant.

Tenant Isolation

OptiFlow uses the stancl/tenancy package:
  1. Each tenant has its own database
  2. Users, tokens, and resources are completely isolated
  3. The tenant is identified by the subdomain in the request URL
  4. Cross-tenant access is not possible, even with valid credentials

Example

# Token for tenant 'acme'
curl https://acme.yourdomain.com/api/v1/invoices \
  -H "Authorization: Bearer acme-token"

# Same token will NOT work for tenant 'techco'
curl https://techco.yourdomain.com/api/v1/invoices \
  -H "Authorization: Bearer acme-token"  # ❌ Fails

Security Best Practices

  • Use environment variables or secure secret management
  • Never hardcode tokens in your application
  • Don’t commit tokens to version control
  • Use different tokens for different environments (dev, staging, production)
  • Always use HTTPS in production
  • Never send tokens over unencrypted HTTP
  • OptiFlow automatically redirects HTTP to HTTPS
  • Generate new tokens periodically
  • Revoke old tokens after rotation
  • Use descriptive token names to track usage
  • Handle 401 responses by refreshing tokens
  • Log authentication failures for security monitoring
  • Don’t expose token values in error messages or logs

Error Responses

401 Unauthorized

Returned when no token is provided or the token is invalid:
{
  "message": "Unauthenticated."
}

403 Forbidden

Returned when the authenticated user lacks required permissions:
{
  "message": "This action is unauthorized."
}

419 Page Expired

Session-based authentication expired (typically for web-based API access):
{
  "message": "CSRF token mismatch."
}

Testing Authentication

Test your authentication setup with a simple request:
curl -X GET https://acme.yourdomain.com/api/v1/users/search \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"
A successful response confirms your token is valid.

Next Steps

Invoices API

Create and manage invoices

Products API

Manage your product catalog

Contacts API

Work with customers and suppliers

Workspaces API

Manage workspace access

Build docs developers (and LLMs) love