> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hydradb.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Database

> Creates a space for storing context. 

export const Field = ({name, type, required, recommended}) => {
  const label = required ? 'required' : recommended ? 'recommended' : null;
  const typeLabel = typeof type === 'string' ? type : null;
  const ariaParts = [name, typeLabel && `${typeLabel}`, label].filter(Boolean);
  return <span aria-label={ariaParts.join(', ')} className={label ? 'field-wrap has-field-tip' : 'field-wrap'} style={{
    position: 'relative',
    cursor: label ? 'default' : undefined
  }} tabIndex={label ? 0 : undefined}>
      <span className="field-name-row">
        <code>{name}</code>
        {required && <span className="field-req"> *</span>}
        {recommended && <span className="field-rec"> ●</span>}
      </span>
      {type && <span className="field-type">{type}</span>}
      {label && <span className="field-tip" role="tooltip">
          {label}
        </span>}
    </span>;
};

<RequestExample>
  ```python Python SDK theme={"dark"}
  response = client.databases.create(
      database="my_first_database",
      database_metadata_schema=[
          {
              "name": "category",
              "data_type": "VARCHAR",
              "max_length": 256,
              "enable_match": True,
          },
          {
              "name": "product_description",
              "data_type": "VARCHAR",
              "max_length": 4096,
              "enable_dense_embedding": True,
              "enable_sparse_embedding": True,
          },
      ],
  )
  ```

  ```typescript TypeScript SDK theme={"dark"}
  const response = await client.databases.create({
    database: "my_first_database",
    databaseMetadataSchema: [
      {
        name: "category",
        dataType: "VARCHAR",
        maxLength: 256,
        enableMatch: true,
      },
      {
        name: "product_description",
        dataType: "VARCHAR",
        maxLength: 4096,
        enableDenseEmbedding: true,
        enableSparseEmbedding: true,
      },
    ],
  });
  ```

  ```bash cURL theme={"dark"}
  curl -X POST 'https://api.hydradb.com/databases' \
    -H "Authorization: Bearer <your_api_key>" \
    -H "API-Version: 2" \
    -H "Content-Type: application/json" \
    -d '{
      "database": "my_first_database",
      "database_metadata_schema": [
        {
          "name": "category",
          "data_type": "VARCHAR",
          "max_length": 256,
          "enable_match": true
        },
        {
          "name": "product_description",
          "data_type": "VARCHAR",
          "max_length": 4096,
          "enable_dense_embedding": true,
          "enable_sparse_embedding": true
        }
      ]
    }'
  ```
</RequestExample>

## Request body

<Note>
  `database` and `collection` are the current field names (formerly `tenant_id` and `sub_tenant_id`). The old names remain accepted as deprecated aliases for full backward compatibility.
</Note>

| Name                                                   | Description                                                                                                                                                                                                                                                                                                    |
| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <Field name="database" type="string" required />       | Account-scoped database identifier. Use a stable, case-sensitive ID up to 25 characters; prefer lowercase letters, numbers, and underscores for portability. Formerly `tenant_id`; the `tenant_id` alias is still accepted (deprecated).                                                                       |
| <Field name="database_metadata_schema" type="array" /> | Defines database-level metadata fields. See the [Scoping using metadata](/essentials/v2/metadata#step-1a-declare-the-schema-at-database-creation) guide for detailed schema parameters. Formerly `tenant_metadata_schema`; the `tenant_metadata_schema` alias is still accepted (deprecated). (default=`null`) |

## Successful response

Always check if a database is ready before using it. Use [Database Status](/api-reference/v2/endpoint/tenant-status) to check.

<ResponseExample>
  ```json Success theme={"dark"}
  {
    "success": true,
    "data": {
      "status": "accepted",
      "database": "my_first_database",
      "message": "Database creation started in the background. Use GET /databases/status?database=... to check progress."
    },
    "error": null,
    "meta": {
      "request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
      "latency_ms": 12.3
    }
  }
  ```

  ```json Failure theme={"dark"}
  {
    "success": false,
    "data": null,
    "error": {
      "code": "DATABASE_ALREADY_EXISTS",
      "message": "Database ID already exists"
    },
    "meta": {
      "request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
      "latency_ms": 4.8
    }
  }
  ```
</ResponseExample>

## What happens after database creation?

1. Create the database with `POST /databases`
2. **Default collection:** No collection exists until your first write. The first time you ingest without an explicit `collection`, HydraDB creates the database's default collection, which then stores all context written without a `collection`. Create additional collections at any time to scope data to users, teams, or projects.
3. **Retry failed databases:** If a database appears in `data.failed_databases`, re-create that database with `POST /databases` after addressing the reported issue. Poll status again before ingestion.
4. Start [ingesting context](/api-reference/v2/endpoint/ingest-context) once databases are ready
5. Check status of [ingestion](/api-reference/v2/endpoint/source-status). Start querying the database once the recently ingested sources show `completed`

***

## Defining metadata schema

<Warning>
  Schema field names are **immutable** after database creation. You can add per-document free-form metadata fields at ingestion time, and add new database-level fields later with [Update Metadata Schema](/api-reference/v2/endpoint/update-metadata-schema), but updates are additive only: no delete, rename, type change, or Milvus backfill for newly added dense/sparse metadata lanes. Plan your schema carefully before creating the database.
</Warning>

You can define a custom schema at database creation to enable exact-match metadata filtering (`enable_match`) or semantic/BM25 search over metadata text fields (`enable_dense_embedding` / `enable_sparse_embedding`).

For detailed parameters, valid data types, limits, shorthand flags, and comprehensive examples, see the [metadata](/essentials/v2/metadata) guide.

***

<div className="api-before-related-resources" />

## **Related Resources**

* **Next:** [Database Status](/api-reference/v2/endpoint/tenant-status) - poll until provisioning completes
* **Next:** [Ingest Context](/api-reference/v2/endpoint/ingest-context) - start ingesting data once status is ready
* **Related:** [Update Metadata Schema](/api-reference/v2/endpoint/update-metadata-schema) - add metadata schema fields later
* **Related:** [Delete Database](/api-reference/v2/endpoint/delete-tenant) - teardown
* **Read more:** [Concepts → Multi-Tenant Support](/essentials/v2/multi-tenant)
* **Read more:** [Usage → Metadata](/essentials/v2/metadata)


## OpenAPI

````yaml api-reference/v2/openapi.json POST /databases
openapi: 3.1.0
info:
  contact:
    email: support@hydradb.com
    name: HydraDB Support
  description: >-
    HydraDB Application API — knowledge ingestion, search, and memory
    management.
  license:
    name: Proprietary
  title: HydraDB Application API
  version: 0.1.0
servers:
  - description: Production server
    url: https://api.hydradb.com
security: []
externalDocs:
  description: ''
  url: ''
paths:
  /databases:
    post:
      tags:
        - database-management
      summary: Create a database
      description: Create a new database with optional custom metadata schema
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/tenants.TenantCreateRequest'
        description: Database creation request
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/handler.Envelope-tenants_TenantCreateAcceptedResponse
          description: OK
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handler.ErrorResponse'
          description: Bad Request
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handler.ErrorResponse'
          description: Forbidden
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handler.ErrorResponse'
          description: Conflict
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/handler.ErrorResponse'
          description: Internal Server Error
      security:
        - BearerAuth: []
components:
  schemas:
    tenants.TenantCreateRequest:
      properties:
        database:
          description: >-
            Database is the canonical v2 name; TenantID is its deprecated alias
            and

            remains fully accepted. The TenantAliases middleware reconciles them
            before

            this binds, so TenantID is always populated.
          example: acme_corp
          type: string
        database_metadata_schema:
          description: >-
            Defines database-level metadata fields for exact-match filtering and
            semantic/BM25 search. Canonical name; `tenant_metadata_schema` is a
            deprecated alias. Schema field names are immutable after database
            creation.
          example:
            - data_type: VARCHAR
              enable_analyzer: false
              enable_dense_embedding: true
              enable_match: true
              enable_sparse_embedding: false
              max_length: 256
              name: category
          items:
            $ref: '#/components/schemas/tenants.CustomPropertyDefinition'
          type: array
          uniqueItems: false
        embeddings_dimension:
          description: 'Override for the embedding vector dimension. Default: 1536.'
          example: 1536
          type: integer
        is_embeddings_tenant:
          description: Internal flag for embedding-only databases.
          example: false
          type: boolean
        tenant_id:
          deprecated: true
          description: 'deprecated: use database'
          example: tenant_1234
          type: string
          x-deprecated: 'true'
        tenant_metadata_schema:
          deprecated: true
          description: 'deprecated: use database_metadata_schema'
          items:
            $ref: '#/components/schemas/tenants.CustomPropertyDefinition'
          type: array
          uniqueItems: false
          x-deprecated: 'true'
      type: object
    handler.Envelope-tenants_TenantCreateAcceptedResponse:
      properties:
        data:
          $ref: '#/components/schemas/tenants.TenantCreateAcceptedResponse'
          example:
            database: acme_corp
            message: Success
            status: completed
            tenant_id: tenant_1234
        error:
          $ref: '#/components/schemas/handler.apiError'
          description: Error message, empty string on success.
          example:
            code: DATABASE_NOT_FOUND
            message: Database not found
        meta:
          $ref: '#/components/schemas/handler.responseMeta'
          example:
            collection: team_docs
            database: acme_corp
            latency_ms: 12.3
            request_id: 9d13aef4-02f4-4e73-8c62-4c2601d04f9d
            source_type: file
            sub_tenant_id: sub_tenant_4567
            tenant_id: tenant_1234
        success:
          description: Whether the request succeeded.
          example: true
          type: boolean
      type: object
    handler.ErrorResponse:
      properties:
        detail:
          $ref: '#/components/schemas/handler.ErrorDetail'
          description: Structured error detail with code, message, and deprecation hints.
          example:
            deprecated: true
            deprecated_field: tenant_id
            error_code: VALIDATION_ERROR
            message: Request validation failed
            preferred_field: database
            success: true
      type: object
    tenants.CustomPropertyDefinition:
      properties:
        data_type:
          $ref: '#/components/schemas/tenants.MilvusDataType'
          description: Milvus data type for this metadata field.
          example: VARCHAR
        enable_analyzer:
          description: >-
            Whether to enable text analysis (tokenization) for BM25 search on
            this field.
          example: false
          type: boolean
        enable_dense_embedding:
          description: Whether to enable semantic (dense) embedding search on this field.
          example: true
          type: boolean
        enable_match:
          description: Whether to enable exact-match filtering on this field.
          example: true
          type: boolean
        enable_sparse_embedding:
          description: Whether to enable BM25 (sparse) embedding search on this field.
          example: false
          type: boolean
        max_length:
          description: Maximum string length in bytes for VARCHAR fields.
          example: 256
          type: integer
        name:
          description: Field name. Immutable after database creation.
          example: category
          type: string
      type: object
    tenants.TenantCreateAcceptedResponse:
      properties:
        database:
          description: >-
            Owning database. Formerly `tenant_id`; the `tenant_id` alias is
            still accepted (deprecated).
          example: acme_corp
          type: string
        message:
          description: Human-readable result message.
          example: Success
          type: string
        status:
          description: Current lifecycle or processing state.
          example: completed
          type: string
        tenant_id:
          deprecated: true
          example: tenant_1234
          type: string
          x-deprecated: 'true'
      type: object
    handler.apiError:
      properties:
        code:
          description: Machine-readable error code (e.g. `DATABASE_NOT_FOUND`).
          example: DATABASE_NOT_FOUND
          type: string
        message:
          description: Human-readable description of the error.
          example: Database not found
          type: string
      type: object
    handler.responseMeta:
      properties:
        collection:
          description: >-
            Collection scope. Defaults to the default collection when omitted.
            Formerly `sub_tenant_id`; the `sub_tenant_id` alias is still
            accepted (deprecated).
          example: team_docs
          type: string
        database:
          description: >-
            Owning database. Formerly `tenant_id`; the `tenant_id` alias is
            still accepted (deprecated).
          example: acme_corp
          type: string
        deprecation:
          description: >-
            Deprecation lists any migration nudges that apply to this request —
            the

            caller used a legacy /tenants route, a legacy
            tenant_id/sub_tenant_id field,

            or the deprecated sub_tenant_ids selector. It is a non-breaking
            signal (the

            status code is unchanged); omitempty keeps it absent for
            fully-migrated

            requests. A list so independent deprecations coexist without
            clobbering.
          items:
            $ref: '#/components/schemas/handler.deprecationNotice'
          type: array
          uniqueItems: false
        latency_ms:
          description: Server-side processing time in milliseconds.
          example: 12.3
          type: number
        request_id:
          description: Unique identifier for this request, useful for support and tracing.
          example: 9d13aef4-02f4-4e73-8c62-4c2601d04f9d
          type: string
        source_type:
          description: Type of the parent source (e.g. `file`, `slack`, `notion`).
          example: file
          type: string
        sub_tenant_id:
          deprecated: true
          example: sub_tenant_4567
          type: string
          x-deprecated: 'true'
        tenant_id:
          deprecated: true
          example: tenant_1234
          type: string
          x-deprecated: 'true'
      type: object
    handler.ErrorDetail:
      properties:
        deprecated:
          description: Whether this response concerns a deprecated field or route.
          example: true
          type: boolean
        deprecated_field:
          description: The deprecated field name.
          example: tenant_id
          type: string
        error_code:
          description: Machine-readable error classification code.
          example: VALIDATION_ERROR
          type: string
        message:
          description: Human-readable description of the error.
          example: Request validation failed
          type: string
        preferred_field:
          description: The canonical replacement for the deprecated field.
          example: database
          type: string
        success:
          description: Always false for error responses.
          example: true
          type: boolean
      type: object
    tenants.MilvusDataType:
      enum:
        - BOOL
        - INT8
        - INT16
        - INT32
        - INT64
        - FLOAT
        - DOUBLE
        - VARCHAR
        - JSON
        - ARRAY
      type: string
      x-enum-varnames:
        - DataTypeBool
        - DataTypeInt8
        - DataTypeInt16
        - DataTypeInt32
        - DataTypeInt64
        - DataTypeFloat
        - DataTypeDouble
        - DataTypeVarchar
        - DataTypeJSON
        - DataTypeArray
    handler.deprecationNotice:
      properties:
        deprecated:
          description: Whether this response concerns a deprecated field or route.
          example: true
          type: boolean
        deprecated_field:
          description: The deprecated field name.
          example: tenant_id
          type: string
        deprecated_since:
          description: API version when the field was deprecated.
          example: 2.0.1
          type: string
        message:
          description: Migration guidance message.
          example: tenant_id is deprecated; use database instead.
          type: string
        preferred_field:
          description: The canonical replacement for the deprecated field.
          example: database
          type: string
      type: object
  securitySchemes:
    BearerAuth:
      bearerFormat: API key
      description: 'API key sent as a Bearer token: "Bearer prefix.secret"'
      scheme: bearer
      type: http

````