API Reference
Complete API documentation for the Identity Service.
Base URL
Production: https://identity.vecton.hu/api
Development: http://localhost:8000/api
Authentication
Most endpoints require authentication via Bearer token:
Authorization: Bearer <your-token>
Response Format
All responses follow this structure:
{
"success": true,
"data": { ... },
"message": "Optional message"
}
Error responses:
{
"success": false,
"message": "Error description",
"errors": {
"field": ["Validation error message"]
}
}
Authentication Endpoints
Login
Authenticate a user and receive an access token.
POST /auth/login
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | User's email address | |
| password | string | Yes | User's password |
| remember | boolean | No | Stay logged in for 30 days |
Example Request:
curl -X POST https://identity.vecton.hu/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "SecurePassword123!",
"remember": true
}'
Success Response (200):
{
"success": true,
"data": {
"token": "1|abc123...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe"
},
"requires_2fa": false,
"requires_pin": false
}
}
2FA Required Response (200):
{
"success": true,
"data": {
"token": "1|abc123...",
"requires_2fa": true,
"requires_pin": false
}
}
Error Response (401):
{
"success": false,
"message": "Invalid credentials"
}
Logout
Invalidate the current access token.
POST /auth/logout
Headers: Requires authentication
Example Request:
curl -X POST https://identity.vecton.hu/api/auth/logout \
-H "Authorization: Bearer YOUR_TOKEN"
Success Response (200):
{
"success": true,
"message": "Successfully logged out"
}
Get Current User
Retrieve the authenticated user's information.
GET /me
Headers: Requires authentication
Success Response (200):
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "660e8400-e29b-41d4-a716-446655440001",
"email": "user@example.com",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"is_active": true,
"email_verified_at": "2026-01-01T00:00:00.000Z",
"last_login_at": "2026-01-29T10:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z"
}
}
Get Security Status
Get the user's security settings status.
GET /me/security
Headers: Requires authentication
Success Response (200):
{
"success": true,
"data": {
"two_factor_enabled": true,
"pin_enabled": false,
"force_password_change": false,
"password_changed_at": "2026-01-15T00:00:00.000Z"
}
}
Password Endpoints
Forgot Password
Request a password reset link.
POST /auth/password/forgot
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | User's email address |
Example Request:
curl -X POST https://identity.vecton.hu/api/auth/password/forgot \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'
Success Response (200):
{
"success": true,
"message": "Password reset link sent if email exists"
}
This endpoint always returns success to prevent email enumeration attacks.
Reset Password
Reset password using the token from email.
POST /auth/password/reset
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| token | string | Yes | Reset token from email |
| string | Yes | User's email address | |
| password | string | Yes | New password (min 12 chars) |
| password_confirmation | string | Yes | Password confirmation |
Success Response (200):
{
"success": true,
"message": "Password has been reset"
}
Error Response (422):
{
"success": false,
"message": "Invalid or expired token",
"errors": {
"token": ["This password reset token is invalid."]
}
}
Change Password
Change password for authenticated user.
POST /auth/password/change
Headers: Requires authentication
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| current_password | string | Yes | Current password |
| new_password | string | Yes | New password (min 12 chars) |
| new_password_confirmation | string | Yes | Password confirmation |
Password Requirements:
- Minimum 12 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
- Cannot be one of the last 5 passwords
Success Response (200):
{
"success": true,
"message": "Password changed successfully"
}
Two-Factor Authentication Endpoints
Enable 2FA
Start the 2FA setup process.
POST /auth/2fa/enable
Headers: Requires authentication
Success Response (200):
{
"success": true,
"data": {
"qr_code": "data:image/png;base64,...",
"secret": "JBSWY3DPEHPK3PXP",
"recovery_codes": [
"abc123-def456",
"ghi789-jkl012",
"mno345-pqr678",
"stu901-vwx234",
"yza567-bcd890",
"efg123-hij456",
"klm789-nop012",
"qrs345-tuv678"
]
}
}
Confirm 2FA
Confirm 2FA setup with a valid TOTP code.
POST /auth/2fa/confirm
Headers: Requires authentication
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | 6-digit TOTP code |
Success Response (200):
{
"success": true,
"message": "Two-factor authentication enabled"
}
Verify 2FA
Verify 2FA code during login.
POST /auth/2fa/verify
Headers: Requires authentication
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | 6-digit TOTP code or recovery code |
Success Response (200):
{
"success": true,
"data": {
"verified": true
}
}
Disable 2FA
Disable two-factor authentication.
POST /auth/2fa/disable
Headers: Requires authentication
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| password | string | Yes | Current password |
Success Response (200):
{
"success": true,
"message": "Two-factor authentication disabled"
}
Regenerate Recovery Codes
Generate new recovery codes.
POST /auth/2fa/recovery-codes
Headers: Requires authentication
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| password | string | Yes | Current password |
Success Response (200):
{
"success": true,
"data": {
"recovery_codes": [
"new123-code456",
"..."
]
}
}
PIN Endpoints
Get PIN Status
Check if PIN is enabled.
GET /auth/pin/status
Headers: Requires authentication
Success Response (200):
{
"success": true,
"data": {
"enabled": true
}
}
Set PIN
Set a new security PIN.
POST /auth/pin/set
Headers: Requires authentication
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| pin | string | Yes | 6-digit PIN |
| pin_confirmation | string | Yes | PIN confirmation |
PIN Rules:
- Exactly 6 digits
- No sequential digits (123456, 654321)
- No repeated digits (000000, 111111)
Success Response (200):
{
"success": true,
"message": "PIN set successfully"
}
Verify PIN
Verify the security PIN.
POST /auth/pin/verify
Headers: Requires authentication
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| pin | string | Yes | 6-digit PIN |
Success Response (200):
{
"success": true,
"data": {
"verified": true
}
}
Disable PIN
Disable the security PIN.
POST /auth/pin/disable
Headers: Requires authentication
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| password | string | Yes | Current password |
Success Response (200):
{
"success": true,
"message": "PIN disabled successfully"
}
Profile Endpoints
Get Profile
Get user profile information.
GET /profile
Headers: Requires authentication
Success Response (200):
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"phone": "+36301234567",
"avatar_url": "https://...",
"timezone": "Europe/Budapest",
"locale": "hu"
}
}
Update Profile
Update user profile information.
PUT /profile
Headers: Requires authentication
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| first_name | string | No | First name |
| last_name | string | No | Last name |
| phone | string | No | Phone number |
| timezone | string | No | Timezone (e.g., Europe/Budapest) |
| locale | string | No | Preferred language (en, hu, de) |
Success Response (200):
{
"success": true,
"data": { ... },
"message": "Profile updated successfully"
}
Get Activity Log
Get user's activity history.
GET /profile/activity
Headers: Requires authentication
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
| page | integer | 1 | Page number |
| per_page | integer | 20 | Items per page (max 100) |
Success Response (200):
{
"success": true,
"data": [
{
"id": "770e8400-e29b-41d4-a716-446655440002",
"action": "user.login",
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"created_at": "2026-01-29T10:00:00.000Z"
}
],
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 20,
"total": 100
}
}
Device Endpoints
List Devices
Get all trusted devices.
GET /devices
Headers: Requires authentication
Success Response (200):
{
"success": true,
"data": [
{
"id": "880e8400-e29b-41d4-a716-446655440003",
"device_name": "Chrome on macOS",
"device_type": "desktop",
"browser": "Chrome",
"os": "macOS",
"ip_address": "192.168.1.1",
"is_current": true,
"last_used_at": "2026-01-29T10:00:00.000Z"
}
]
}
Revoke Device
Remove a trusted device.
POST /devices/{id}/revoke
Headers: Requires authentication
Success Response (200):
{
"success": true,
"message": "Device revoked successfully"
}
OAuth2 / System Auth Endpoints
For system-to-system authentication.
Get Access Token
POST /oauth/token
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| grant_type | string | Yes | "client_credentials" |
| client_id | string | Yes | Application client ID |
| client_secret | string | Yes | Application client secret |
| scope | string | No | Requested scopes |
Success Response (200):
{
"access_token": "eyJ0eXAiOiJKV1Q...",
"token_type": "Bearer",
"expires_in": 3600
}
Introspect Token
Validate an access token.
POST /oauth/introspect
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| token | string | Yes | Access token to validate |
| client_id | string | Yes | Application client ID |
| client_secret | string | Yes | Application client secret |
Success Response (200):
{
"active": true,
"client_id": "app-123",
"exp": 1706540400,
"scope": "read write"
}
Revoke Token
Revoke an access token.
POST /oauth/revoke
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
| token | string | Yes | Token to revoke |
| client_id | string | Yes | Application client ID |
| client_secret | string | Yes | Application client secret |
Success Response (200):
{
"success": true
}
Health Check
GET /health
Success Response (200):
{
"status": "ok",
"service": "identity",
"timestamp": "2026-01-29T10:00:00.000Z",
"version": "1.0.0"
}
Error Codes
| HTTP Code | Description |
|---|---|
| 200 | Success |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 422 | Validation Error |
| 429 | Too Many Requests (Rate Limited) |
| 500 | Internal Server Error |
Rate Limits
| Endpoint | Limit |
|---|---|
| /auth/login | 5 requests per minute |
| /auth/password/forgot | 5 requests per hour |
| /auth/2fa/verify | 5 requests per minute |
| /auth/pin/verify | 5 requests per minute |
| Other endpoints | 60 requests per minute |