Authentication API Endpoints
This document contains the API contract specifications for authentication-related endpoints in the RestartiX application.
API Conventions
- Base path:
/v1/(versioned from day one) - Content-Type:
application/jsonfor all request/response bodies - Authentication: Clerk session token in
Authorization: Bearer <token>header - Organization context: Determined by user's
current_organization_id(set via/me/switch-organization) - Errors: Consistent
{ "error": { "code": "...", "message": "..." } }format
Standard Response Formats
Single Resource
json
{
"data": {
"id": 1,
"title": "Initial Consultation",
"status": "upcoming",
"created_at": "2025-01-15T10:30:00Z"
}
}Error
json
{
"error": {
"code": "appointment_not_found",
"message": "Appointment not found",
"details": null
}
}Validation Error
json
{
"error": {
"code": "validation_error",
"message": "Validation failed",
"details": {
"fields": {
"email": "must be a valid email address",
"name": "is required"
}
}
}
}Endpoints
GET /v1/me
Returns the current authenticated user with organization context.
Authentication: Required - Clerk session token
Request: No body required
Response: 200
json
{
"data": {
"id": 42,
"email": "[email protected]",
"username": "[email protected]",
"role": "specialist",
"confirmed": true,
"last_activity": "2025-01-15T14:22:00Z",
"current_organization": {
"id": 1,
"name": "RestartiX",
"slug": "restartix"
},
"organization_ids": [1, 3],
"specialist_id": 2,
"specialist_name": "Dr. Smith",
"patient_id": null
}
}Notes:
- This endpoint provides the full user context including their current organization
- The
organization_idsarray shows all organizations the user belongs to - Role-specific IDs are included (
specialist_id,patient_id) withnullfor non-applicable roles last_activitytimestamp is useful for session management
PUT /v1/me/switch-organization
Switch the user's active organization context.
Authentication: Required - Clerk session token
Request:
json
{
"organization_id": 3
}Response: 200
json
{
"data": {
"current_organization": {
"id": 3,
"name": "HealthCorp",
"slug": "healthcorp"
},
"message": "Organization switched successfully"
}
}Errors:
403 forbidden- User is not a member of this organization404 organization_not_found- Organization doesn't exist
Notes:
- The user must be a member of the target organization (must exist in their
organization_idsarray) - After switching, all subsequent API requests will be scoped to the new organization context
- This affects data visibility, RLS policies, and available resources
POST /webhooks/clerk
Clerk webhook endpoint for user sync events. Verified by Clerk signature.
Authentication: Verified by Clerk webhook signature (not user token)
Events handled:
user.created→ Create internal user recorduser.updated→ Update email/usernameuser.deleted→ Soft-delete or block user
Request: The request body follows Clerk's webhook event format. The structure varies by event type.
Response: 200
json
{
"success": true
}Notes:
- This endpoint is called by Clerk's servers, not by client applications
- Request verification is done via Clerk's webhook signature in the request headers
- Used to keep internal user records synchronized with Clerk's authentication system
- Handles user lifecycle events from Clerk
- Should implement idempotency to handle duplicate webhook deliveries
- Error responses should still return 200 to prevent Clerk from retrying valid but already-processed events
Error Code Reference
| Code | HTTP | Description |
|---|---|---|
validation_error | 400 | Input validation failed |
unauthorized | 401 | Missing or invalid auth token |
forbidden | 403 | Insufficient permissions |
not_found | 404 | Resource not found |
conflict | 409 | Resource already exists or state conflict |
rate_limited | 429 | Too many requests |
internal_error | 500 | Unexpected server error |
service_unavailable | 502 | External service unavailable |
organization_not_found | 404 | Organization doesn't exist |