Skip to main content

List Tenants

GET /v1/console/tenants
List all tenants in the system.

Authentication

Requires TENANT_MANAGEMENT.can_view permission.

Query parameters

skip
integer
default:"0"
Number of records to skip.
limit
integer
default:"20"
Max records to return (1-100).
include_inactive
boolean
default:"false"
Include soft-deleted tenants.

Example request

curl "https://mind-be.staging.miva.university/v1/console/tenants?limit=10" \
  -H "Authorization: Bearer <access_token>"

Response

{
  "success": true,
  "data": [
    {
      "id": "6650a1b2c3d4e5f6a7b8c9d0",
      "name": "Demo University",
      "slug": "demo-university",
      "domain": "demo.miva.university",
      "lms_type": "canvas",
      "is_active": true,
      "created_at": "2025-01-01T00:00:00Z"
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 10,
  "total_pages": 1,
  "message": null
}

Create Tenant

POST /v1/console/tenants
Create a new tenant. Branding, SSO, and AI config are configured separately after creation.

Authentication

Requires TENANT_MANAGEMENT.can_create permission.

Request body

name
string
required
Tenant display name. Max 255 characters.
slug
string
required
URL-safe identifier. Lowercase alphanumeric and hyphens only (^[a-z0-9-]+$). Max 100 characters.
domain
string
Custom domain for the tenant. Max 255 characters.
lms_type
string
LMS integration type (e.g. canvas, blackboard, moodle). Max 50 characters.

Example request

curl -X POST https://mind-be.staging.miva.university/v1/console/tenants \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "State University",
    "slug": "state-university",
    "domain": "state.miva.university",
    "lms_type": "canvas"
  }'

Response

{
  "success": true,
  "data": {
    "id": "6650c3d4e5f6a7b8c9d0e1f2",
    "name": "State University",
    "slug": "state-university",
    "domain": "state.miva.university",
    "lms_type": "canvas",
    "is_active": true,
    "created_at": "2025-06-01T14:00:00Z",
    "updated_at": null,
    "branding": null,
    "sso_config": null,
    "ai_config": null,
    "allowed_origins": []
  },
  "message": "Tenant created successfully"
}

Error responses

StatusCodeCondition
409CONFLICTSlug already taken
422VALIDATION_ERRORInvalid slug format

Get Tenant

GET /v1/console/tenants/{tenant_id}
Get a tenant’s full configuration including branding, SSO, and AI settings.

Authentication

Requires TENANT_MANAGEMENT.can_view permission.

Path parameters

tenant_id
string
required
The tenant’s ID.

Example request

curl https://mind-be.staging.miva.university/v1/console/tenants/6650c3d4e5f6a7b8c9d0e1f2 \
  -H "Authorization: Bearer <access_token>"

Response

{
  "success": true,
  "data": {
    "id": "6650c3d4e5f6a7b8c9d0e1f2",
    "name": "State University",
    "slug": "state-university",
    "domain": "state.miva.university",
    "lms_type": "canvas",
    "is_active": true,
    "created_at": "2025-06-01T14:00:00Z",
    "updated_at": null,
    "branding": {
      "logo_url": "https://cdn.example.com/logo.png",
      "primary_color": "#1E3A5F",
      "secondary_color": "#F5A623",
      "widget_position": "bottom-right"
    },
    "sso_config": {
      "provider": "cas",
      "server_url": "https://cas.state.edu",
      "callback_url": "https://app.state.edu/cas/callback",
      "is_enabled": true
    },
    "ai_config": {
      "default_llm_model": "gpt-4o",
      "default_tts_voice": "alloy",
      "default_stt_language": "en",
      "max_sessions_per_student": 5,
      "default_language": "en",
      "admin_email": "admin@state.edu",
      "support_email": "support@state.edu"
    },
    "allowed_origins": ["https://app.state.edu"]
  },
  "message": null
}

Update Tenant

PATCH /v1/console/tenants/{tenant_id}
Update a tenant’s core fields. For branding, SSO, and AI config, use their dedicated endpoints.

Authentication

Requires TENANT_MANAGEMENT.can_edit permission.

Path parameters

tenant_id
string
required
The tenant’s ID.

Request body

name
string
Updated name.
slug
string
Updated slug.
domain
string
Updated domain.
lms_type
string
Updated LMS type.
is_active
boolean
Active status.

Example request

curl -X PATCH https://mind-be.staging.miva.university/v1/console/tenants/6650c3d4e5f6a7b8c9d0e1f2 \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "lms_type": "blackboard"
  }'

Response

Returns the full updated tenant object (same shape as Get Tenant).

Delete Tenant

DELETE /v1/console/tenants/{tenant_id}
Soft-delete a tenant. All users under the tenant will lose access.

Authentication

Requires TENANT_MANAGEMENT.can_delete permission.

Path parameters

tenant_id
string
required
The tenant’s ID.

Example request

curl -X DELETE https://mind-be.staging.miva.university/v1/console/tenants/6650c3d4e5f6a7b8c9d0e1f2 \
  -H "Authorization: Bearer <access_token>"

Response

Returns the soft-deleted tenant object with is_active: false.

Update Branding

PATCH /v1/console/tenants/{tenant_id}/branding
Update the tenant’s branding configuration.

Authentication

Requires TENANT_MANAGEMENT.can_edit permission.

Path parameters

tenant_id
string
required
The tenant’s ID.

Request body

logo_url
string
URL to the tenant’s logo. Max 500 characters.
primary_color
string
Hex color code, e.g. #1E3A5F.
secondary_color
string
Hex color code.
widget_position
string
One of: bottom-right, bottom-left, top-right, top-left.

Example request

curl -X PATCH https://mind-be.staging.miva.university/v1/console/tenants/6650c3d4e5f6a7b8c9d0e1f2/branding \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "primary_color": "#1E3A5F",
    "secondary_color": "#F5A623"
  }'

Response

{
  "success": true,
  "data": {
    "logo_url": null,
    "primary_color": "#1E3A5F",
    "secondary_color": "#F5A623",
    "widget_position": "bottom-right"
  },
  "message": "Branding updated successfully"
}

Update SSO Config

PATCH /v1/console/tenants/{tenant_id}/sso
Configure CAS SSO settings for the tenant.

Authentication

Requires TENANT_MANAGEMENT.can_edit permission.

Path parameters

tenant_id
string
required
The tenant’s ID.

Request body

provider
string
SSO provider (e.g. cas).
server_url
string
CAS server base URL.
callback_url
string
Callback URL after CAS authentication.
is_enabled
boolean
Enable or disable SSO.

Example request

curl -X PATCH https://mind-be.staging.miva.university/v1/console/tenants/6650c3d4e5f6a7b8c9d0e1f2/sso \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "cas",
    "server_url": "https://cas.state.edu",
    "callback_url": "https://app.state.edu/cas/callback",
    "is_enabled": true
  }'

Response

{
  "success": true,
  "data": {
    "provider": "cas",
    "server_url": "https://cas.state.edu",
    "callback_url": "https://app.state.edu/cas/callback",
    "is_enabled": true
  },
  "message": "SSO config updated successfully"
}

Update AI Config

PATCH /v1/console/tenants/{tenant_id}/ai-config
Configure default AI settings for the tenant.

Authentication

Requires TENANT_MANAGEMENT.can_edit permission.

Path parameters

tenant_id
string
required
The tenant’s ID.

Request body

default_llm_model
string
Default LLM model name.
default_tts_voice
string
Default text-to-speech voice.
default_stt_language
string
Default speech-to-text language code.
max_sessions_per_student
integer
Max session attempts per student per case study.
default_language
string
Default UI language code.
admin_email
string
Admin notification email.
support_email
string
Support contact email.

Example request

curl -X PATCH https://mind-be.staging.miva.university/v1/console/tenants/6650c3d4e5f6a7b8c9d0e1f2/ai-config \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "default_llm_model": "gpt-4o",
    "max_sessions_per_student": 5
  }'

Response

{
  "success": true,
  "data": {
    "default_llm_model": "gpt-4o",
    "default_tts_voice": null,
    "default_stt_language": null,
    "max_sessions_per_student": 5,
    "default_language": null,
    "admin_email": null,
    "support_email": null
  },
  "message": "AI config updated successfully"
}

Get Allowed Origins

GET /v1/console/tenants/{tenant_id}/allowed-origins
Get the CORS allowed origins list for a tenant.

Authentication

Requires TENANT_MANAGEMENT.can_view permission.

Path parameters

tenant_id
string
required
The tenant’s ID.

Example request

curl https://mind-be.staging.miva.university/v1/console/tenants/6650c3d4e5f6a7b8c9d0e1f2/allowed-origins \
  -H "Authorization: Bearer <access_token>"

Response

{
  "success": true,
  "data": ["https://app.state.edu", "https://staging.state.edu"],
  "message": null
}

Add Allowed Origin

POST /v1/console/tenants/{tenant_id}/allowed-origins
Add a CORS origin to the tenant’s allowed list.

Authentication

Requires TENANT_MANAGEMENT.can_edit permission.

Path parameters

tenant_id
string
required
The tenant’s ID.

Request body

origin
string
required
The origin URL to allow (e.g. https://app.state.edu).

Example request

curl -X POST https://mind-be.staging.miva.university/v1/console/tenants/6650c3d4e5f6a7b8c9d0e1f2/allowed-origins \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{ "origin": "https://newapp.state.edu" }'

Response

Returns the full updated list of allowed origins.

Remove Allowed Origin

DELETE /v1/console/tenants/{tenant_id}/allowed-origins/{origin}
Remove a CORS origin. The origin path parameter must be URL-encoded.

Authentication

Requires TENANT_MANAGEMENT.can_edit permission.

Path parameters

tenant_id
string
required
The tenant’s ID.
origin
string
required
The origin URL to remove (URL-encoded).

Example request

curl -X DELETE "https://mind-be.staging.miva.university/v1/console/tenants/6650c3d4e5f6a7b8c9d0e1f2/allowed-origins/https%3A%2F%2Fnewapp.state.edu" \
  -H "Authorization: Bearer <access_token>"

Response

{
  "success": true,
  "data": null,
  "message": "Origin removed successfully"
}