Skip to main content

POST /api/v1/register

Create a new user account. Optionally creates an associated tenant business at the same time. Middleware: throttle:api
Authentication: Not required

Request body

name
string
required
Full display name of the user. Maximum 255 characters.
email
string
required
Unique email address. Must not already exist in the users table.
password
string
required
Password. Must meet Laravel’s default password complexity rules and pass confirmation.
password_confirmation
string
required
Must match the password field.
tenant_name
string
Optional business name. When provided, a tenant record is created and linked to this user. The slug is auto-generated from this name.

Headers

X-Idempotency-Key
string
Optional idempotency key. Falls back to the idempotency_key body field if not present.

Response 201 Created

data
object
curl -X POST https://yourdomain.com/api/v1/register \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "name": "Ana García",
    "email": "[email protected]",
    "password": "SecurePass123!",
    "password_confirmation": "SecurePass123!",
    "tenant_name": "Mi Negocio"
  }'

Error responses

StatusCause
422Validation failure (duplicate email, weak password, fields missing)

POST /api/v1/otp/generate

Generate a one-time password sent to the provided email or phone number. Middleware: throttle:api.otp-generation, idempotency
Authentication: Not required

Request body

identifier
string
required
Email address or international phone number (e.g. +50488887777). Must be a valid email or match the pattern +[country_code][number].

Response 200 OK

{
  "message": "Codigo enviado exitosamente.",
  "expires_at": "2026-03-19T14:30:00+00:00"
}
message
string
Confirmation that the code was sent.
expires_at
string
ISO 8601 timestamp when the OTP expires (default: 10 minutes from generation).
curl -X POST https://yourdomain.com/api/v1/otp/generate \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"identifier": "[email protected]"}'

Error responses

StatusCause
422identifier missing or not a valid email/phone format
429OTP generation rate limit exceeded

POST /api/v1/otp/verify

Verify a one-time password. On success, returns user context and a redirect path. Middleware: throttle:api.verification
Authentication: Not required

Request body

uuid
string
required
UUID identifier for the OTP session — passed as a UUID-formatted string representing the session identifier.
otp_code
string
required
Exactly 6 numeric digits.

Response 200 OK — existing user

{
  "message": "Autenticacion exitosa.",
  "user": { "id": "<user-uuid>", "tenant_id": "<tenant-uuid>" },
  "requires_registration": false,
  "redirect": "/dashboard"
}
message
string
Success message.
user
object
requires_registration
boolean
false for existing users.
redirect
string
Client redirect path (/dashboard).

Response 200 OK — new user (no account found)

{
  "message": "Verificacion exitosa. Completa tu registro.",
  "user": null,
  "requires_registration": true,
  "redirect": "/register"
}
curl -X POST https://yourdomain.com/api/v1/otp/verify \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"uuid": "550e8400-e29b-41d4-a716-446655440000", "otp_code": "482719"}'

Error responses

StatusCause
422UUID invalid format, OTP not numeric, wrong code, or code expired
429Verification rate limit exceeded

POST /api/v1/auth/social

Authenticate via an OAuth provider. Accepts a provider token from the client-side OAuth flow and returns a Sanctum bearer token. Middleware: throttle:api
Authentication: Not required

Request body

provider
string
required
OAuth provider name. Must be one of: google, facebook, apple, github, twitter.
token
string
required
OAuth access token from the provider. Maximum 4096 characters.
provider_id
string
required
Unique user identifier from the OAuth provider. Maximum 255 characters.
email
string
required
Email from the OAuth profile. Must be a valid RFC + DNS-validated address.
name
string
Display name from the OAuth profile. Defaults to the email prefix when omitted.
avatar
string
Profile image URL from the OAuth profile. Maximum 2048 characters.

Headers

Idempotency-Key
string
Optional idempotency key. Auto-generated as a UUID if not supplied.

Response 200 OK

user
object
token
string
Bearer token (social-api-token).
redirect_to
string
Suggested redirect path: /dashboard for existing users, /onboarding for new users that require onboarding.
curl -X POST https://yourdomain.com/api/v1/auth/social \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "provider": "google",
    "token": "ya29.A0ARrdaM...",
    "provider_id": "118257938745938",
    "email": "[email protected]",
    "name": "Ana García",
    "avatar": "https://lh3.googleusercontent.com/photo.jpg"
  }'

Error responses

StatusCause
422Unsupported provider, token too long, invalid email, missing required fields
422Tenant context could not be resolved

GET /api/v1/user

Return the currently authenticated user. Middleware: auth:sanctum, throttle:api
Authentication: Required

Response 200 OK

Returns the raw Eloquent user model serialized to JSON. Key fields include id, name, email, and tenant_id.
curl -X GET https://yourdomain.com/api/v1/user \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN"

Error responses

StatusCause
401Missing or invalid bearer token

Build docs developers (and LLMs) love