Skip to main content
The REST API uses Laravel Sanctum for stateless token authentication. Every protected API request must carry a Bearer token in the Authorization header.
API routes live under the /api/v1 prefix. No session cookie is accepted — the auth:sanctum guard validates only the token.

Obtaining a token

Registering via the API issues a Sanctum token in the same response.
POST /api/v1/register
Content-Type: application/json

Request body

name
string
required
Full name of the user.
email
string
required
Email address. Must be unique across all users.
password
string
required
Minimum 8 characters. Must be confirmed.
password_confirmation
string
required
Must match password.
tenant_name
string
required
Display name of the organization (up to 255 characters).
tenant_domain
string
required
URL-safe slug for the organization. Must be unique across all tenants (alpha_dash format).

Response 201 Created

{
  "user": {
    "id": "uuid",
    "name": "Jane Smith",
    "email": "[email protected]"
  },
  "token": "1|abc123...",
  "redirect_to": "/dashboard"
}
The Location header is also set to the user profile URL: GET /api/v1/user.
user.id
string
UUID of the newly created user.
user.email
string
Email address of the user.
token
string
Sanctum personal access token. Include this in subsequent requests.
redirect_to
string
Suggested client-side redirect path after registration.

Using the token

Pass the token in every authenticated request:
curl https://your-app.com/api/v1/user \
  -H "Authorization: Bearer 1|abc123..."
const response = await fetch('/api/v1/user', {
  headers: {
    Authorization: `Bearer ${token}`,
    Accept: 'application/json',
  },
});

Protected routes

Routes that require a valid Sanctum token use middleware('auth:sanctum').

User profile

GET /api/v1/user
Authorization: Bearer {token}
Returns the authenticated user record.

Tenant-scoped routes

The following groups require both auth:sanctum and tenant.ownership middleware:
ResourceRoutes
OrdersGET /api/v1/orders, GET /api/v1/orders/{order}, PATCH /api/v1/orders/{order}/status, DELETE /api/v1/orders/{order}
SettingsGET /api/v1/settings, POST /api/v1/settings/update
ReportsGET /api/v1/reports/sales/excel, GET /api/v1/reports/sales/pdf, GET /api/v1/reports/inventory/pdf, GET /api/v1/reports/kitchen/pdf
ExportsPOST /api/v1/exports/sales
NotificationsGET /api/v1/notifications, GET /api/v1/notifications/count, PATCH /api/v1/notifications/read-all, PATCH /api/v1/notifications/{id}/read
AI toolsPOST /api/v1/ai/generate, POST /api/v1/ai/optimize-profile
The tenant.ownership middleware checks every route-model-bound parameter against the authenticated user’s tenants. A mismatch returns 404 and logs a TENANT_OWNERSHIP_VIOLATION security event — it does not return 403 to avoid disclosing resource existence.

Token scopes and revocation

Tokens are named at creation time (api-token for registration, social-api-token for social login). Vito does not currently define granular Sanctum token abilities — every token grants full API access for the owning user. To revoke a token, delete it from the personal_access_tokens table or use Laravel’s currentAccessToken()->delete() in a logout action.

Push subscriptions

Authenticated users can register a browser for Web Push notifications.

Register a push subscription

POST /api/v1/push-subscriptions
Authorization: Bearer {token}
Content-Type: application/json

{
  "endpoint": "https://fcm.googleapis.com/fcm/send/...",
  "keys": {
    "p256dh": "...",
    "auth": "..."
  },
  "contentEncoding": "aesgcm"
}
endpoint
string
required
The push service URL provided by the browser (max 1000 characters).
keys.p256dh
string
required
Elliptic-curve Diffie-Hellman public key.
keys.auth
string
required
Auth secret from the browser’s push subscription.
contentEncoding
string
Encryption scheme. Defaults to aesgcm.

Remove a push subscription

DELETE /api/v1/push-subscriptions
Authorization: Bearer {token}
Content-Type: application/json

{
  "endpoint": "https://fcm.googleapis.com/fcm/send/..."
}
Both endpoints require auth:sanctum and return { "status": "success" } on success.

Build docs developers (and LLMs) love