Skip to main content
POST
/
user
/
create_tenant
Create Tenant
curl --request POST \
  --url https://api.usecortex.ai/user/create_tenant \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "tenant_metadata_schema": [
    {
      "key": "department",
      "type": "string",
      "searchable": true,
      "filterable": true
    },
    {
      "key": "compliance_framework",
      "type": "string",
      "searchable": true,
      "filterable": false
    },
    {
      "key": "data_classification",
      "type": "string",
      "searchable": false,
      "filterable": true
    }
  ]
}'
{
  "status": "created",
  "tenant_id": "tenant_1234",
  "success": true,
  "message": "Tenant created successfully"
}
Create a new tenant. If you pass tenant_id as a query parameter, that ID will be used. If not provided, the service generates a new tenant_id and returns it.
Hit the Try it button to try this API now in our playground. It’s the best way to check the full request and response in one place, customize your parameters, and generate ready-to-use code snippets.

Sample Request:

curl --request POST \
  --url 'https://api.usecortex.ai/user/create_tenant?tenant_id=tenant_1234' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "tenant_metadata_schema": [
    {
      "key": "department",
      "type": "string",
      "searchable": true,
      "filterable": true
    },
    {
      "key": "compliance_framework",
      "type": "string",
      "searchable": true,
      "filterable": false
    },
    {
      "key": "data_classification",
      "type": "string",
      "searchable": false,
      "filterable": true
    }
  ]
}'
Important: When a tenant is created, Cortex automatically creates a DEFAULT sub-tenant that acts as a global space for that tenant. Any documents ingested or API calls made with the tenant_id but without specifying a sub_tenant_id will automatically reference this default sub-tenant.

Creating Additional Sub-Tenants

No Separate API Required: Cortex doesn’t require a separate API call to create additional sub-tenants. Sub-tenants are created automatically when you first use a new sub_tenant_id that doesn’t exist yet.

How Sub-Tenant Creation Works

  1. Automatic Creation: When you upload content with a sub_tenant_id that doesn’t exist, Cortex automatically creates that sub-tenant
  2. First Upload Triggers Creation: The first API call with a new sub_tenant_id will create the sub-tenant and then process your content
  3. Immediate Availability: Once created, the sub-tenant is immediately available for all subsequent operations

Sub-Tenant ID Best Practices

For B2C Applications (Individual Users):
// Use user IDs as sub-tenant IDs for personal workspaces
sub_tenant_id: "user_12345"
sub_tenant_id: "user_67890"
For B2B Applications (Departments/Teams):
// Use descriptive department or team names
sub_tenant_id: "engineering"
sub_tenant_id: "sales"
sub_tenant_id: "hr"
sub_tenant_id: "marketing"
For Project-Based Organizations:
// Use project identifiers
sub_tenant_id: "project_alpha"
sub_tenant_id: "client_acme_corp"
Naming Convention: Use consistent prefixes like user_, dept_, or project_ to make the purpose of each sub-tenant clear. Avoid special characters and keep names descriptive but concise.
Important: Tenant metadata keys are immutable once set during tenant creation. Choose your keys carefully as they cannot be modified later. Document metadata remains fully flexible and can be set per document during upload.

Reserved Keywords

The following keywords are reserved and cannot be used as keys in tenant_metadata_schema:
  • source_id
  • source_title
  • source_url
  • source_type
  • source_collection
  • source_owner
  • source_collaborator
  • source_upload_time
  • source_last_updated_time
  • chunk_id
  • chunk_uuid
  • chunk_content
  • document_metadata
  • base_metadata
  • layout
  • description
These keywords are used internally by Cortex for document processing and search functionality. Using any of these reserved keywords as tenant metadata keys will result in an error during tenant creation.

Metadata Schema Structure

Each schema object in the tenant_metadata_schema array should specify:
  • key: The metadata field name (immutable once set)
  • type: Data type (see supported types below)
  • searchable: Whether this field can be used in search queries
  • filterable: Whether this field can be used for filtering

Supported Metadata Types

Cortex supports a comprehensive range of data types for metadata fields:

Primitive Types

TypeDescriptionExample ValuesUse Cases
stringText data"Engineering", "SOC2", "confidential"Categorical data, identifiers, labels
numberNumeric values5, 100.5, 2024Quantitative metrics, versions, priorities
booleanTrue/false valuestrue, falseBinary flags, status indicators
dateDate/time values"2024-01-15T10:30:00Z"Temporal data, audit trails

Complex Types

TypeDescriptionExample ValuesUse Cases
objectStructured data{"city": "SF", "country": "USA"}Hierarchical relationships, nested data
arrayMultiple values["security", "api", "compliance"]Multi-value attributes, tags, categories

Searchable vs Filterable Flags

Understanding the difference between searchable and filterable is crucial for optimal metadata design: 1. Searchable Fields
  • Purpose: Fields that can be used in semantic search queries and QnA operations
  • Behavior: Content is indexed for AI-powered search and question answering
  • Use When: You want users to find documents by asking questions about these fields
  • Example: "Which documents are from the Engineering department?"
{
  "key": "department", 
  "type": "string", 
  "searchable": true,  // ✅ Can be searched semantically
  "filterable": true
}
2. Filterable Fields
  • Purpose: Fields that can be used for precise filtering and exact matching
  • Behavior: Content is indexed for fast exact-match filtering operations
  • Use When: You want to narrow down results with precise criteria
  • Example: department = "Engineering" AND status = "active"
{
  "key": "data_classification", 
  "type": "string", 
  "searchable": false,  // ❌ Not semantically searchable
  "filterable": true    // ✅ Can be filtered exactly
}
3. Combined Usage
{
  "key": "compliance_framework", 
  "type": "string", 
  "searchable": true,   // ✅ "Find SOC2 compliance documents"
  "filterable": true    // ✅ compliance_framework = "SOC2"
}

Comprehensive Examples

Enterprise Setup - Multi-Department Organization
[
  {
    "key": "department", 
    "type": "string", 
    "searchable": true, 
    "filterable": true
  },
  {
    "key": "compliance_framework", 
    "type": "string", 
    "searchable": true, 
    "filterable": true
  },
  {
    "key": "data_classification", 
    "type": "string", 
    "searchable": false, 
    "filterable": true
  },
  {
    "key": "business_unit", 
    "type": "string", 
    "searchable": true, 
    "filterable": true
  },
  {
    "key": "retention_period", 
    "type": "number", 
    "searchable": false, 
    "filterable": true
  },
  {
    "key": "is_confidential", 
    "type": "boolean", 
    "searchable": false, 
    "filterable": true
  },
  {
    "key": "created_date", 
    "type": "date", 
    "searchable": false, 
    "filterable": true
  }
]
Legal Firm Setup - Client and Case Management
[
  {
    "key": "practice_area", 
    "type": "string", 
    "searchable": true, 
    "filterable": true
  },
  {
    "key": "client_id", 
    "type": "string", 
    "searchable": false, 
    "filterable": true
  },
  {
    "key": "confidentiality_level", 
    "type": "string", 
    "searchable": false, 
    "filterable": true
  },
  {
    "key": "jurisdiction", 
    "type": "string", 
    "searchable": true, 
    "filterable": true
  },
  {
    "key": "case_priority", 
    "type": "number", 
    "searchable": false, 
    "filterable": true
  },
  {
    "key": "requires_approval", 
    "type": "boolean", 
    "searchable": false, 
    "filterable": true
  }
]
Engineering Team Setup - Project and Component Management
[
  {
    "key": "product_line", 
    "type": "string", 
    "searchable": true, 
    "filterable": true
  },
  {
    "key": "team", 
    "type": "string", 
    "searchable": true, 
    "filterable": true
  },
  {
    "key": "component", 
    "type": "string", 
    "searchable": true, 
    "filterable": true
  },
  {
    "key": "priority", 
    "type": "number", 
    "searchable": false, 
    "filterable": true
  },
  {
    "key": "is_critical", 
    "type": "boolean", 
    "searchable": false, 
    "filterable": true
  },
  {
    "key": "tags", 
    "type": "array", 
    "searchable": true, 
    "filterable": true
  }
]
Simple Setup - Basic Organization
[
  {
    "key": "organization", 
    "type": "string", 
    "searchable": true, 
    "filterable": true
  },
  {
    "key": "environment", 
    "type": "string", 
    "searchable": true, 
    "filterable": true
  },
  {
    "key": "version", 
    "type": "string", 
    "searchable": false, 
    "filterable": true
  }
]

Metadata Best Practices

1. Naming Conventions
  • Use snake_case: business_unit instead of businessUnit
  • Be descriptive: data_classification_level instead of classification
  • Use consistent prefixes: compliance_*, security_*, business_*
2. Type Selection Guidelines
  • Strings: For categorical data, identifiers, and labels
  • Numbers: For quantitative metrics, versions, and priorities
  • Booleans: For binary flags and status indicators
  • Dates: For temporal data and audit trails
  • Arrays: For multi-value fields like tags and categories
  • Objects: For structured, hierarchical data
3. Searchable vs Filterable Strategy
  • Make searchable: Fields users will ask questions about
  • Make filterable: Fields used for precise result narrowing
  • Combine both: For fields used in both semantic search and filtering
  • Filterable only: For sensitive data or exact-match requirements
4. Performance Considerations
  • Limit total fields: Keep metadata schema focused and purposeful
  • Use appropriate types: Choose the most specific type for your data
  • Consider query patterns: Design for your most common use cases
  • Plan for growth: Design schema to accommodate future needs

How Metadata Works in Practice

Once you’ve defined your tenant metadata schema, here’s how it works with your documents:

Document Upload with Metadata

When you upload documents, you’ll provide both tenant and document metadata:
{
  "tenant_metadata": {
    "department": "Engineering",
    "compliance_framework": "SOC2",
    "data_classification": "internal",
    "business_unit": "Product",
    "retention_period": 7,
    "is_confidential": false,
    "created_date": "2024-01-15T10:30:00Z"
  },
  "document_metadata": {
    "title": "API Security Guidelines v2.1",
    "author": "Dr. Sarah Chen",
    "document_type": "technical_specification",
    "version": "2.1.0",
    "status": "approved"
  }
}

Query Examples

With the metadata schema defined above, users can perform sophisticated queries:

Semantic Search (Searchable Fields)

"Find all engineering documents about security compliance"
  • Searches through department (searchable: true)
  • Searches through compliance_framework (searchable: true)
  • Searches through document content and titles

Precise Filtering (Filterable Fields)

department = "Engineering" AND data_classification = "internal" AND is_confidential = false
  • Exact match on department (filterable: true)
  • Exact match on data_classification (filterable: true)
  • Exact match on is_confidential (filterable: true)

Combined Queries

"Show me all SOC2 compliance documents from the Product business unit"
  • Semantic search for “SOC2 compliance” (searchable fields)
  • Precise filter: business_unit = "Product" (filterable: true)

Real-World Use Cases

Schema: Practice area, client ID, confidentiality level, jurisdiction Query: “Find all corporate law documents for client ACME that are not confidential” Filter: practice_area = "corporate_law" AND client_id = "ACME" AND confidentiality_level != "confidential"

2. Engineering Documentation

Schema: Product line, team, component, priority, tags Query: “Show me all high-priority API documentation from the backend team” Filter: product_line = "API" AND team = "backend" AND priority >= 4

3. HR Document Management

Schema: Department, employee type, salary band, status Query: “Find all active full-time employees in the Engineering department” Filter: department = "Engineering" AND employee_type = "full_time" AND status = "active"

Metadata Inheritance

All documents in your tenant automatically inherit the tenant metadata schema you define. This means:
  1. Consistency: Every document will have the same tenant metadata structure
  2. Compliance: Organizational policies are enforced across all documents
  3. Queryability: You can always filter and search by tenant-level attributes
  4. Scalability: New documents automatically follow your established schema

Migration and Updates

Schema Immutability: Once you create a tenant with a metadata schema, the keys cannot be changed. However, you can:
  • Add new fields to document metadata (fully flexible)
  • Update values for existing tenant metadata fields
  • Create new sub-tenants with different schemas if needed
Note:
  • The tenant_metadata_schema field in the request body is optional but recommended for enterprise setups. It defines immutable tenant-level metadata keys that will apply to all documents in this tenant.
  • For more detailed information about metadata usage, filtering, and querying, see our Metadata documentation.

Sample Response

{
  "status": "success",
  "message": "Tenant '99155#$@e2' created successfully.",
  "tenant_id": "B1SlKQ2j2l1aWYLa"
}

Functionality

  • Accepts an optional tenant_id via query
  • Generates a new tenant_id if none is provided
  • Creates and persists the tenant
  • Returns the final tenant_id and a confirmation message
Note: If your use case is to directly upload and search embeddings (without document/text ingestion), use the dedicated embeddings-tenant endpoint instead: /embeddings/create_tenant. This sets sub_tenant_id = tenant_id and prepares the tenant for embeddings-first workloads.

Error Responses

All endpoints return consistent error responses following the standard format. For detailed error information, see our Error Responses documentation.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Query Parameters

tenant_id
string | null
default:""

Unique identifier for the tenant/organization

Example:

"tenant_1234"

note
string
default:""
Example:

"<str>"

Body

application/json
tenant_metadata_schema
Tenant Metadata Schema · object[] | null
Example:
[
{
"key": "department",
"type": "string",
"searchable": true,
"filterable": true
},
{
"key": "compliance_framework",
"type": "string",
"searchable": true,
"filterable": false
},
{
"key": "data_classification",
"type": "string",
"searchable": false,
"filterable": true
}
]

Response

Successful Response

status
string
required

Current status of the tenant creation process

Example:

"created"

tenant_id
string
required

Unique identifier assigned to the new tenant

Example:

"tenant_1234"

success
boolean
default:true

Indicates whether the tenant creation was successful

Example:

true

message
string
default:Tenant created successfully

Response message describing the creation result

I