Skip to content

Specialist API Endpoints

All specialist endpoints are org-scoped and require Clerk authentication. The authenticated user's organization is resolved from the Clerk session.

Authentication & Authorization

HeaderValue
AuthorizationBearer <clerk_session_token>

Permissions:

  • SELECT (list, get): All authenticated users in the organization
  • CREATE, UPDATE, DELETE: Admin role only

Base URL

All endpoints use the /v1/ prefix.


List Specialists

GET /v1/specialists

List specialists for the authenticated organization. Automatically filtered by RLS.

Query Parameters:

  • ?page=1 - Page number (default: 1)
  • ?page_size=25 - Results per page (max: 100, default: 25)
  • ?sort=-created_at - Sort order (minus prefix = descending)
  • ?include=specialties,user - Include related resources
  • ?deleted=false - Filter by soft delete status (default: false, only active specialists)

Response: 200

json
{
  "data": [
    {
      "id": 2,
      "organization_id": 1,
      "user_id": 44,
      "name": "Dr. Jane Smith",
      "title": "Cardiologist",
      "description": "Board-certified cardiologist with 15 years of experience...",
      "slug": "dr-jane-smith",
      "signature_url": "https://s3.amazonaws.com/restartix/signatures/smith-sig.png",
      "avatar_url": "https://s3.amazonaws.com/restartix/avatars/smith.jpg",
      "scheduling_timezone": "America/New_York",
      "scheduling_active": true,
      "minicrm_name": "DrSmith",
      "deleted_at": null,
      "created_at": "2025-01-10T08:00:00Z",
      "updated_at": "2025-01-15T10:30:00Z",
      "specialties": [
        {"id": 1, "title": "Cardiology", "slug": "cardiology"},
        {"id": 3, "title": "Internal Medicine", "slug": "internal-medicine"}
      ]
    }
  ],
  "meta": {
    "page": 1,
    "page_size": 25,
    "total": 5,
    "total_pages": 1
  }
}

Create Specialist

POST /v1/specialists

Create a new specialist. Admin only.

Request:

json
{
  "name": "Dr. Jane Smith",
  "title": "Cardiologist",
  "description": "Board-certified cardiologist with 15 years of experience in cardiovascular health.",
  "slug": "dr-jane-smith",
  "user_id": 44,
  "specialty_ids": [1, 3],
  "scheduling_timezone": "America/New_York",
  "scheduling_active": true,
  "minicrm_name": "DrSmith"
}

Validation:

  • name (required, 1-200 chars)
  • slug (required, unique per organization, lowercase alphanumeric + hyphens)
  • user_id (optional, must reference existing user in the same organization)
  • specialty_ids (optional array, each ID must reference existing specialty in the same org)
  • scheduling_timezone (optional, must be valid IANA timezone)
  • scheduling_active (optional, default: true)

Response: 201

json
{
  "data": {
    "id": 2,
    "organization_id": 1,
    "user_id": 44,
    "name": "Dr. Jane Smith",
    "title": "Cardiologist",
    "description": "Board-certified cardiologist with 15 years of experience in cardiovascular health.",
    "slug": "dr-jane-smith",
    "signature_url": null,
    "avatar_url": null,
    "scheduling_timezone": "America/New_York",
    "scheduling_active": true,
    "minicrm_name": "DrSmith",
    "deleted_at": null,
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": "2025-01-15T10:30:00Z"
  }
}

Errors:

  • 400 name_required - Name is required
  • 400 slug_required - Slug is required
  • 400 invalid_slug - Slug must be lowercase alphanumeric with hyphens
  • 409 slug_exists - A specialist with this slug already exists in this organization
  • 404 user_not_found - User ID references a non-existent user
  • 404 specialty_not_found - One or more specialty IDs are invalid
  • 400 invalid_timezone - Timezone is not a valid IANA timezone
  • 403 forbidden - User does not have admin role

Get Specialist

GET /v1/specialists/{id}

Get a single specialist by ID with all details.

Query Parameters:

  • ?include=specialties,user,weekly_hours,overrides - Include related resources

Response: 200

json
{
  "data": {
    "id": 2,
    "organization_id": 1,
    "user_id": 44,
    "name": "Dr. Jane Smith",
    "title": "Cardiologist",
    "description": "Board-certified cardiologist with 15 years of experience...",
    "slug": "dr-jane-smith",
    "signature_url": "https://s3.amazonaws.com/restartix/signatures/smith-sig.png",
    "avatar_url": "https://s3.amazonaws.com/restartix/avatars/smith.jpg",
    "scheduling_timezone": "America/New_York",
    "scheduling_active": true,
    "minicrm_name": "DrSmith",
    "deleted_at": null,
    "created_at": "2025-01-10T08:00:00Z",
    "updated_at": "2025-01-15T10:30:00Z",
    "specialties": [
      {"id": 1, "title": "Cardiology", "slug": "cardiology"},
      {"id": 3, "title": "Internal Medicine", "slug": "internal-medicine"}
    ],
    "user": {
      "id": 44,
      "email": "[email protected]",
      "username": "[email protected]",
      "role": "specialist"
    }
  }
}

Errors:

  • 404 specialist_not_found - Specialist doesn't exist or not accessible in current organization

Update Specialist

PUT /v1/specialists/{id}

Update a specialist. Admin only.

Request:

json
{
  "name": "Dr. Jane Marie Smith",
  "title": "Senior Cardiologist",
  "description": "Updated biography...",
  "specialty_ids": [1, 3, 5],
  "scheduling_timezone": "Europe/Bucharest",
  "scheduling_active": false
}

Validation:

  • All fields are optional
  • Same validation rules as POST for fields that are provided
  • Cannot change id, organization_id, created_at
  • scheduling_timezone change is blocked if appointment-type-specific overrides exist for this specialist

Field Protection:

  • Patients and specialists can view specialists but cannot modify
  • Only admins can update specialist records

Response: 200

json
{
  "data": {
    "id": 2,
    "organization_id": 1,
    "user_id": 44,
    "name": "Dr. Jane Marie Smith",
    "title": "Senior Cardiologist",
    "description": "Updated biography...",
    "slug": "dr-jane-smith",
    "signature_url": "https://s3.amazonaws.com/restartix/signatures/smith-sig.png",
    "avatar_url": "https://s3.amazonaws.com/restartix/avatars/smith.jpg",
    "scheduling_timezone": "Europe/Bucharest",
    "scheduling_active": false,
    "minicrm_name": "DrSmith",
    "deleted_at": null,
    "created_at": "2025-01-10T08:00:00Z",
    "updated_at": "2025-01-15T11:45:00Z"
  }
}

Errors:

  • 404 specialist_not_found - Specialist doesn't exist or not accessible
  • 403 forbidden - User does not have admin role
  • 409 slug_exists - Another specialist already has this slug in the organization
  • 400 timezone_locked - Cannot change timezone while appointment-type-specific overrides exist
  • 404 user_not_found - User ID references a non-existent user
  • 404 specialty_not_found - One or more specialty IDs are invalid

Delete Specialist

DELETE /v1/specialists/{id}

Soft-delete a specialist. Admin only. Sets deleted_at timestamp instead of removing the record (medical record integrity / HIPAA compliance).

Response: 200

json
{
  "data": {
    "id": 2,
    "message": "Specialist soft-deleted successfully",
    "deleted_at": "2025-01-15T12:00:00Z"
  }
}

Business Logic:

  1. Validate specialist exists and belongs to current organization
  2. Check user has admin role
  3. Set deleted_at = NOW()
  4. Historical appointments and clinical records remain intact
  5. Specialist no longer appears in active listings
  6. Can be filtered with ?deleted=true to view soft-deleted records

Errors:

  • 404 specialist_not_found - Specialist doesn't exist or not accessible
  • 403 forbidden - User does not have admin role
  • 409 already_deleted - Specialist is already soft-deleted

Integration Notes

Scheduling System Integration

For scheduling-related operations (weekly hours, overrides, availability), see:


For specialty management, see the Specialty endpoints:

  • GET /v1/specialties - List all specialties
  • POST /v1/specialties - Create specialty
  • GET /v1/specialties/{id} - Get specialty with specialists
  • PUT /v1/specialties/{id} - Update specialty
  • DELETE /v1/specialties/{id} - Delete specialty