Admin - Tenant

Manage tenants under your Admin account. View tenant details, usage statistics, and list users within each tenant.

List Tenants

Get all tenants.

Endpoint

GET /v1/admin/tenants

Query Parameters

  • limit (optional): Number of results (1-1000, default: 100)
  • offset (optional): Pagination offset (default: 0)

Example Query

curl 'https://ai.hatz.ai/v1/admin/tenants?limit=50&offset=0' \
  -H 'X-API-Key: $HATZ_API_KEY'

Response

[
  {
    "id": "tenant_abc123",
    "name": "Acme Corporation",
    "primary_package_name": "Professional",
    "additional_package_names": ["1500 Extra Credits"],
    "user_count": 25,
    "status": "Active",
    "created_at": "2024-01-15T09:00:00Z",
    "total_credits_used": 15000,
    "total_credit_limit": 50000,
    "tenant_config": {
      "beta_features": false,
      "mfa_required": false,
      "default_model_name": "gpt-4o"
    },
    "disabled_model_names": []
  }
]

Get own MSP

Retrieve details about the internal admin (MSP).

Endpoint

GET /v1/admin/tenants/msp

Example Query

curl 'https://ai.hatz.ai/v1/admin/tenants/msp' \
  -H 'X-API-Key: $HATZ_API_KEY'

Response

{
  "name": "Internal Admin MSP",
  "created_at": "2023-01-01T00:00:00Z",
  "primary_package_name": "Enterprise",
  "additional_package_names": [],
  "packages": {},
  "total_credits_used": 125000,
  "total_credit_limit": 500000,
  "admin_user_count": 5,
  "admin_recent_signin_count": 3,
  "admin_login_rate": 0.6,
  "tenant_user_count": 150,
  "tenant_recent_signin_count": 85,
  "tenant_login_rate": 0.57
}

Get Tenant Details

Retrieve details for a specific tenant by ID.

Endpoint

GET /v1/admin/tenants/{tenant_id}

Path Parameters

  • tenant_id: Tenant ID (e.g., "tenant_abc123")

Example Query

curl 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123' \
  -H 'X-API-Key: $HATZ_API_KEY'

Response

{
  "id": "tenant_abc123",
  "name": "Acme Corporation",
  "primary_package_name": "Professional",
  "additional_package_names": [],
  "user_count": 25,
  "status": "Active",
  "created_at": "2024-01-15T09:00:00Z",
  "total_credits_used": 15000,
  "total_credit_limit": 50000,
  "tenant_config": {
    "beta_features": false,
    "mfa_required": true,
    "default_model_name": "gpt-4o"
  },
  "disabled_model_names": ["claude-3-opus"]
}

Get Tenant Users

Get all users belonging to a specific tenant.

Endpoint

GET /v1/admin/tenants/{tenant_id}/users

Path Parameters

  • tenant_id (required): Tenant ID (e.g., "tenant_abc123")

Query Parameters

  • limit (optional): Number of results (1-1000, default: 100)
  • offset (optional): Pagination offset (default: 0)

Example Request

curl 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/users?limit=50&offset=0' \
  -H 'X-API-Key: $HATZ_API_KEY'

Response

[
  {
    "id": "user_xyz789",
    "email": "john.doe@acme.com",
    "first_name": "John",
    "last_name": "Doe",
    "tenant_id": "tenant_abc123",
    "role_name": "client_admin",
    "last_sign_in_at": "2024-06-15T14:30:00Z",
    "invitation_status": "Active"
  },
  {
    "id": "user_abc456",
    "email": "jane.smith@acme.com",
    "first_name": "Jane",
    "last_name": "Smith",
    "tenant_id": "tenant_abc123",
    "role_name": "general_user",
    "last_sign_in_at": null,
    "invitation_status": "Provisioned"
  }
]

Create Tenants

Create one or more tenants with optional users.

Endpoint

POST /v1/admin/tenants

Request Body

  • tenants (required): List of tenants to create (1-100, or 1-20 when purchase=true)
    • tenant_name (required): Tenant name (1-255 characters). Must be globally unique across all entities (not MSP-scoped). This is enforced server-side; a request will fail if the name already exists.
    • package_id (optional): Package ID (e.g., "package_xyz"). Required if template_id not provided.
    • template_id (optional): Tenant template ID (e.g., "tentemplate_xyz"). Required if package_id not provided.
    • users (optional): Initial users for the tenant (max 1000 per tenant)
      • email (required): User email address
      • first_name (optional): User first name
      • last_name (optional): User last name
      • role (optional): Default role name (e.g., "general_user", "client_admin")
      • custom_role_name (optional): Custom role slug (e.g., "engineering_lead"). Must be an MSP-wide role since the tenant does not exist yet.
      • role and custom_role_name are mutually exclusive. If neither is provided, the general_user default role is used.
  • purchase (optional): Whether to automatically purchase a license if none are available. Defaults to false. When enabled, the tenants list is capped at 20. **The caller must have billing access on the account to use this option (role of billing manager, admin or primary admin) **
  • send_email (optional): Whether to send invitation emails immediately to created users. Defaults to true. When enabled, the total number of users across all tenants is capped at 1000. Set to false to bypass this limit and provision users without sending emails.

Note -- when purchase is false (default), there must be an existing unassigned package in the account that matches the type specified by the incoming package or template ID in order to create the new tenant and assign a package to them.

Request

{
  "tenants": [                             // Required: Array of tenants to create (1-100, or 1-20 when purchase=true)
    {
      "tenant_name": "string",             // Required: Tenant name (1-255 characters)
      "package_id": "string",              // Optional: Package ID (e.g., "package_xyz"). Required if template_id not provided
      "template_id": "string",             // Optional: Template ID (e.g., "tentemplate_xyz"). Required if package_id not provided
      "users": [                           // Optional: Array of users
        {
          "email": "string",
          "first_name": "string",           // Optional
          "last_name": "string",            // Optional
          "role": "string",              // Optional: Default role name (e.g., "general_user")
          "custom_role_name": "string"   // Optional: Custom role slug (e.g., "engineering_lead"). Must be MSP-wide.
        }
      ]
    }
  ],
  "purchase": false,                       // Optional: Auto-purchase license if unavailable (default: false, requires billing access)
  "send_email": true                       // Optional: Whether to send invitation emails immediately to created users (default: true)
}

Custom roles on tenant creation: When assigning a custom_role_name to users during tenant creation, the role must be an MSP-wide custom role since the tenant does not exist yet and tenant-scoped roles cannot be referenced. Use GET /v1/admin/roles (without a tenant_id) to list your MSP-wide custom roles and their name slugs.

Example Request

curl -X POST 'https://ai.hatz.ai/v1/admin/tenants' \
  -H 'X-API-Key: $HATZ_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "tenants": [
      {
        "tenant_name": "Acme Corporation",
        "package_id": "package_abc123",
        "users": [
          {
            "email": "admin@acme.com",
            "first_name": "John",
            "last_name": "Doe",
            "role": "client_admin"
          }
        ]
      }
    ]
  }'

Response

{
  "message": "Successfully created 1 tenants",
  "total_tenants_created": 1,
  "total_tenants_failed": 0,
  "tenants": [
    {
      "tenant_name": "Acme Corporation",
      "tenant_id": "tenant_def456",
      "success": true,
      "error": null,
      "total_new_users_created": 1,
      "total_new_users_failed": 0,
      "new_users_failed_emails": [],
      "purchase_occurred": false
    }
  ]
}

Update Tenant Configuration

Update tenant configuration settings including beta features, MFA requirements, and default AI model.

Endpoint

PATCH /v1/admin/tenants/{tenant_id}/config

Path Parameters

  • tenant_id (required): Tenant ID (e.g., "tenant_abc123")

Request Body

  • beta_features (optional): Enable or disable beta features
  • mfa_required (optional): Require MFA for all users in tenant
  • default_model_name (optional): Default AI model name (e.g., "gpt-4o"). Set to empty string to clear.

Example Request

curl -X PATCH 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/config' \
  -H 'X-API-Key: $HATZ_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "beta_features": true,
    "mfa_required": true,
    "default_model_name": "gpt-4o"
  }'

Response

{
  "beta_features": true,
  "mfa_required": true,
  "default_model_name": "gpt-4o"
}

Get Disabled LLMs

Retrieve the list of AI models that are disabled for a specific tenant. Disabled models are unavailable to tenant users in chat and workshop items.

Endpoint

GET /v1/admin/tenants/{tenant_id}/disabled-llms

Path Parameters

  • tenant_id (required): Tenant ID (e.g., "tenant_abc123")

Example Query

curl 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/disabled-llms' \
  -H 'X-API-Key: $HATZ_API_KEY'

Response

{
  "disabled_model_names": ["claude-3-opus", "gpt-4"]
}

An empty list means all models are enabled for the tenant:

{
  "disabled_model_names": []
}

Update Disabled LLMs

Replace the list of disabled AI models for a tenant. Pass an empty list to enable all models.

Endpoint

PUT /v1/admin/tenants/{tenant_id}/disabled-llms

Path Parameters

  • tenant_id (required): Tenant ID (e.g., "tenant_abc123")

Request Body

  • disabled_model_names (required): List of AI model names to disable. Replaces the existing list entirely.

Example Request

curl -X PUT 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/disabled-llms' \
  -H 'X-API-Key: $HATZ_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "disabled_model_names": ["claude-3-opus", "gpt-4"]
  }'

Response

{
  "disabled_model_names": ["claude-3-opus", "gpt-4"]
}

Error Responses

  • 400 — One or more model names not found or not enabled

Update Tenant Package

Update the package assigned to a tenant. Accepts a package HashID and schedules the package change.

Endpoint

PUT /v1/admin/tenants/{tenant_id}/package

Path Parameters

  • tenant_id (required): Tenant ID (e.g., "tenant_abc123")

Request Body

  • package_id (required): Package HashID (e.g., "package_abc123")

Example Request

curl -X PUT 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/package' \
  -H 'X-API-Key: $HATZ_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "package_id": "package_xyz789"
  }'

Response

{
  "message": "Package update scheduled successfully",
  "error": null,
  "scheduled_activation": "2024-07-01T00:00:00Z"
}

Error Responses

  • 400 — Invalid package ID format
  • 403 — Insufficient permissions to access package data
  • 404 — Package could not be found
  • 502 — Error executing update

Bulk Resend Tenant Invitation Emails

Resend invitation emails to all users in a tenant that match a given invitation status. This is useful for bulk-sending invitations to all provisioned users who haven't received an invite yet, or resending to all previously invited users.

Endpoint

POST /v1/admin/tenants/{tenant_id}/resend-invitation-email

Path Parameters

  • tenant_id (required): Tenant ID (e.g., "tenant_abc123")

Request Body

{
  "status": "string",  // Required: "Invited" or "Provisioned"
  "limit": 1000        // Optional: Max emails to send (1-1000, default: 1000)
}

Invitation statuses:

  • Active — User has signed in at least once.
  • Invited — User was created and sent an invitation email but has not signed in yet.
  • Provisioned — User was created without an invitation email (e.g., send_email was set to false, or the user was SCIM-provisioned).

If there are more matching users than the limit, the response will indicate how many were sent. Call the endpoint again to send to the next batch.

Example Query

curl -X POST 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/resend-invitation-email' \
  -H 'X-API-Key: $HATZ_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "status": "Provisioned"
  }'

Response

{
  "message": "Successfully sent 5 invitation emails",
  "total_sent": 5,
  "total_failed": 0,
  "failed_emails": []
}

Get Auto-Invite Configuration

Retrieve the automatic account creation and invite link configuration for a tenant. Returns the current enabled state, a pre-built invite URL (when a link exists), the default role for sign-ups, and allowed email domain restrictions.

Endpoint

GET /v1/admin/tenants/{tenant_id}/auto-invite

Path Parameters

  • tenant_id (required): Tenant ID (e.g., "tenant_abc123")

Example Request

curl 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/auto-invite' \
  -H 'X-API-Key: $HATZ_API_KEY'

Response

{
  "auto_account_creation_enabled": true,
  "invite_url": "https://yourworkspace.hatz.ai/join/acme-corp-abc123xyz",
  "default_invite_role": {
    "role_id": "role_abc123",
    "role_source": "default",
    "role_name": "general_user"
  },
  "allowed_email_domains": ["acme.com"],
  "has_saml_connection": false
}

invite_url is null when automatic account creation has never been enabled, after it is disabled, or after the link is revoked. default_invite_role is null when no role is configured.

role_source is "default" for built-in platform roles or "custom" for MSP/tenant-scoped custom roles.

Update Auto-Invite Configuration

Enable or disable automatic account creation for a tenant and configure its invite link settings. Enabling for the first time generates an invite link automatically. Disabling clears the invite link but preserves the role and domain settings so they don't need to be reconfigured when re-enabling.

Endpoint

PUT /v1/admin/tenants/{tenant_id}/auto-invite

Path Parameters

  • tenant_id (required): Tenant ID (e.g., "tenant_abc123")

Request Body

{
  "enabled": true,
  "default_invite_role_id": "role_abc123",
  "allowed_email_domains": ["acme.com"]
}
  • enabled (required): Whether to enable automatic account creation.
  • default_invite_role_id (required when enabling, unless using name): Role HashID (e.g. role_abc123). Use GET /v1/admin/tenants/{tenant_id}/roles to list valid IDs.
  • default_invite_role_name (alternative to role_id): Slug of a default platform role (e.g. "general_user", "client_admin").
  • default_invite_custom_role_name (alternative to role_id): Slug of a custom role scoped to this MSP or tenant.
  • allowed_email_domains (optional): List of email domains allowed to self-register. Empty list removes all domain restrictions (max 50 domains).

Provide exactly one of default_invite_role_id, default_invite_role_name, or default_invite_custom_role_name when enabling. If multiple are provided, role_id takes precedence, then role_name, then custom_role_name.

Note: Automatic account creation cannot be enabled when the tenant has an SSO/SAML connection configured.

Example Request

curl -X PUT 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/auto-invite' \
  -H 'X-API-Key: $HATZ_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "enabled": true,
    "default_invite_role_id": "role_abc123",
    "allowed_email_domains": ["acme.com"]
  }'

Response

Same shape as Get Auto-Invite Configuration.

Error Responses

  • 400 — Role selection is incomplete, role is invalid for this tenant, or SAML conflict

Revoke the current invite link and generate a new one. Any existing link immediately stops working. Returns the new full invite URL.

Endpoint

POST /v1/admin/tenants/{tenant_id}/invite-link/regenerate

Path Parameters

  • tenant_id (required): Tenant ID (e.g., "tenant_abc123")

Example Request

curl -X POST 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/invite-link/regenerate' \
  -H 'X-API-Key: $HATZ_API_KEY'

Response

{
  "invite_url": "https://yourworkspace.hatz.ai/join/acme-corp-newtoken123"
}

Error Responses

  • 400 — Tenant has no parent MSP entity
  • 404 — Invite settings not found (AAC has never been enabled for this tenant)
  • 500 — Unable to resolve workspace domain

List all tenants under your MSP that currently have an active invite link, along with their configuration and full invite URLs.

Endpoint

GET /v1/admin/invite-links

Query Parameters

Parameter Type Default Description
limit integer 100 Maximum number of results (1–500).
offset integer 0 Number of results to skip.

Example Request

curl 'https://ai.hatz.ai/v1/admin/invite-links?limit=50&offset=0' \
  -H 'X-API-Key: $HATZ_API_KEY'

Response

{
  "items": [
    {
      "tenant_id": "tenant_abc123",
      "tenant_name": "Acme Corporation",
      "invite_url": "https://yourworkspace.hatz.ai/join/acme-corp-abc123xyz",
      "auto_account_creation_enabled": true,
      "default_role_name": "general_user",
      "created_at": "2024-01-15T09:00:00Z"
    }
  ],
  "total": 42,
  "limit": 50,
  "offset": 0
}

default_role_name is null when no default role is configured for a link.

Use offset and total to paginate: if offset + limit < total, fetch the next page by incrementing offset by limit.