Skip to content

API System

The starter includes a comprehensive API system designed for secure, monitored programmatic access to your application. The system provides token-based authentication, IP allowlisting, request logging, and detailed analytics.

The starter ships with a minimal set of API endpoints to support access token management and viewing user information. They live in routes/api.php and can be removed or extended as needed.

  • GET /api/health — Unauthenticated health check, exposed when API_ENABLED=true
  • GET /api/v1/me — Returns the authenticated API user profile
  • GET /api/v1/me/tokens — Paginated list of the user’s access tokens
  • POST /api/v1/me/tokens — Create a new access token
  • GET /api/v1/me/tokens/{token} — Fetch a single access token
  • DELETE /api/v1/me/tokens/{token} — Revoke an access token

View the API Specification for a complete reference of these endpoints. If your project does not need these defaults, delete or adjust the corresponding routes in routes/api.php.

The API architecture is designed to separate human identity from machine identity, utilizing a strict one-to-many relationship between API Users and their Access Tokens.

An API User represents a specific machine actor.

  • Distinct from Humans - Separate from standard user accounts. They cannot log in through the UI.
  • Scoped Authority - They can only be assigned API Integration roles to ensure they are never granted elevated permissions.

Each API user can possess multiple Access Tokens. These are the actual credentials used in the Authorization header.

  • Immediate Activation - Tokens are valid immediately upon creation.
  • Optional Expiration - Tokens can be set to expire after a certain date, or remain valid indefinitely.
  • Granular Restrictions - Each token can have its own specific IP allowlist, independent of other tokens belonging to the same user.

In production environments, it is best practice to issue a unique token for every distinct service connecting to your API, even if they represent the same “API User” or organization.

  • Isolation - A single compromised integration does not jeopardize others
  • Safe Rotation - Rotate one token without interrupting other consumers
  • Better Analytics - Usage logs are tied to the specific token. This allows you to see granular usage patterns per integration.
  • Multi-Token Architecture - Create unique credentials for every consumer
  • Flexible Lifecycles - Choose between ephemeral tokens with hard expiration dates or permanent keys for long-term usage
  • Easy Revocation - Invalidate compromised credentials instantly through the administration panel
  • CIDR Notation Support - Restrict access to specific subnets (e.g., 10.0.0.0/24) or single IPs
  • Multi-Origin Support - Allow a single token to be used from multiple distinct locations
  • Performance Metrics - Every request is timed and logged, allowing you to spot slow endpoints
  • Traffic Analysis - Built-in charts visualize API usage, error rates, and endpoint popularity over time
  • Sampling - Configurable logging rates to prevent database bloat in high-traffic environments
  1. Token Creation

    An administrator creates an API user and generates a token through the administration panel. During creation, you may optionally set an Expiration. If omitted, the token remains valid indefinitely.

  2. Token Delivery

    The plain-text token is displayed once at creation. Be sure to copy and store it securely, as it cannot be retrieved later.

    Bearer Token: abc123def456ghi789jkl012mno345pqr678stu901vwx234yz
  3. Client Request

    The external client includes the token in the request header:

    GET /api/users HTTP/1.1
    Host: your-app.northwestern.edu
    Authorization: Bearer abc123def456ghi789jkl012mno345pqr678stu901vwx234yz
  4. System Validation

    The middleware performs a sequence of checks:

    1. Format: Extracts the Bearer token
    2. Identity: Locates the API User by the token hash
    3. Validity: Checks if the token has been revoked or expired
    4. Security: Verifies the request IP matches the allowlist (if configured)
    5. Authorization: Grants access based on the API User’s assigned role(s)
  5. Logging

    After the response is sent, the system logs the request details for monitoring and analytics.

To prevent service interruptions, the system automatically sends email notifications when a token is approaching its expiration date and the API User has an email address configured.

By default, notifications are sent 30, 14, 7, and 3 days before expiration, as well as on the final day.

You can adjust these intervals in the configuration:

config/auth.php
'expiration_notifications' => [
'enabled' => env('API_ACCESS_TOKEN_EXPIRATION_NOTIFICATIONS_ENABLED', true),
'intervals' => [30, 14, 7, 3, 1],
],

If you do not wish to send expiration notifications, you can disable this feature entirely:

.env
API_ACCESS_TOKEN_EXPIRATION_NOTIFICATIONS_ENABLED=false

Requests to protected API endpoints are automatically logged to the api_request_logs table. This provides a lightweight mechanism for monitoring API usage and debugging issues.

Every log entry includes:

FieldDescription
trace_idUnique request identifier
user_idID of the authenticated user
access_token_idID of the Access Token used for authentication (nullable)
methodHTTP method (GET, POST, etc.)
pathRequest path (relative URL)
route_nameNamed route for the request (if applicable)
ip_addressSource IP address
status_codeHTTP status code
duration_msRequest duration in milliseconds
response_bytesSize of the response body in bytes (if measurable)
user_agentUser agent string from the request (if provided)
failure_reasonAuthentication or request failure reason, if any
created_atTimestamp when the request was logged

To manage the database load, you can configure probabilistic sampling through environment variables:

.env
API_REQUEST_LOGGING_SAMPLING_ENABLED=true
API_REQUEST_LOGGING_SAMPLING_RATE=0.1 // Log 10% of requests

This is a basic utility, not a replacement for full-scale observability solutions.

Database-based logging is immensely helpful during local development to spot slow endpoints, and monitor low-traffic non-production environments.

For production applications expecting high volume:

  • Opt for a dedicated APM: Use legitimate tools like New Relic or Datadog for deeper insights and to avoid database bloat.
  • Adjust sampling: If you keep this feature enabled in production, consider setting a very low sampling rate (or disabling it entirely) to avoid the database write overhead.

To handle granular access control for API users, the system leverages the existing role and permission structure.

API users can ONLY be assigned roles with a role type of API Integration. This is intentionally restrictive to prevent API users from being granted permissions that are not relevant or appropriate for programmatic access.

When creating/editing API Integration roles, only permissions marked as API-relevant are presented for assignment. These are determined by the isApiRelevant() method on the PermissionEnum:

app/Domains/User/Enums/PermissionEnum.php
public function isApiRelevant(): bool
{
return match ($this) {
self::VIEW_USERS => true,
default => false,
};
}

As you add new permissions to the system, ensure to update this method accordingly.