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

# Create a draft tenant

> Requires the `onboarding_admin` control role; unlike every other mutating route on this router, this one does not enforce CSRF. Validates the slug format (422 if invalid) and returns 409 if the slug is already taken, then inserts a `draft` `control.tenants` row and writes a `control.audit_log` row (`tenant_created`). Does not provision the tenant's Postgres schema -- call `POST /admin/tenants/{tenant_id}/provision` next. Returns 201 with the created tenant's summary.



## OpenAPI

````yaml /api-reference/openapi.json post /admin/tenants
openapi: 3.1.0
info:
  title: CL MVP Product API
  description: >-
    The Causeloop MVP Product API is a deliberately small, explicitly
    allowlisted HTTP surface: `services/api/product_app.py` enumerates every one
    of the 44 published (method, path) operations drawn from seven routers, and
    only those operations are mounted onto this app -- everything else defined
    in the underlying routers (and the entire legacy research surface in
    `services/api/main.py`) is not exposed here. Staff (employee) and
    tenant-user sessions are separate cookie-based principals with no shared
    session table; mutating requests are protected by a double-submit CSRF
    cookie/header pair. See `/api-reference/authentication` for session and CSRF
    details, and `/api-reference/errors-and-conventions` for shared error shapes
    and status-code conventions.
  version: 1.0.0
servers: []
security: []
tags:
  - name: Auth
    description: >-
      Staff (employee) and tenant-user session lifecycle: login/logout,
      current-identity reads, invitation acceptance, and the public pre-login
      workspace directory.
  - name: Staff Onboarding
    description: >-
      The Onboarding Portal surface used to create, provision, ingest data for,
      train, activate, and go-live a tenant. Every operation requires an
      authenticated employee session; mutations additionally require the
      `onboarding_admin` control role (`support_readonly` employees can read but
      not write).
  - name: Insights
    description: >-
      Tenant-facing reads of materialized insight collections (themes, severity,
      issues, fishbone, and related model outputs) produced by the training and
      materialization pipeline.
  - name: Members
    description: Read-only tenant member directory.
  - name: Sources
    description: Tenant-facing source-connector registration and file-upload ingest.
  - name: Remediation
    description: >-
      Tenant-scoped corrective action plans (CAPs), human-in-the-loop issue
      reviews, the tenant audit trail, and the branded Excel export.
  - name: Health & Observability
    description: >-
      Unauthenticated liveness/readiness probes and the employee-only Prometheus
      metrics scrape endpoint.
paths:
  /admin/tenants:
    post:
      tags:
        - Staff Onboarding
      summary: Create a draft tenant
      description: >-
        Requires the `onboarding_admin` control role; unlike every other
        mutating route on this router, this one does not enforce CSRF. Validates
        the slug format (422 if invalid) and returns 409 if the slug is already
        taken, then inserts a `draft` `control.tenants` row and writes a
        `control.audit_log` row (`tenant_created`). Does not provision the
        tenant's Postgres schema -- call `POST
        /admin/tenants/{tenant_id}/provision` next. Returns 201 with the created
        tenant's summary.
      operationId: create_tenant_admin_tenants_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTenantRequest'
        required: true
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TenantSummary'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    CreateTenantRequest:
      properties:
        slug:
          type: string
          maxLength: 63
          minLength: 3
          title: Slug
        name:
          type: string
          title: Name
        industry:
          anyOf:
            - type: string
            - type: 'null'
          title: Industry
        region:
          anyOf:
            - type: string
            - type: 'null'
          title: Region
        data_residency_notes:
          anyOf:
            - type: string
            - type: 'null'
          title: Data Residency Notes
        primary_contact_email:
          anyOf:
            - type: string
            - type: 'null'
          title: Primary Contact Email
      type: object
      required:
        - slug
        - name
      title: CreateTenantRequest
    TenantSummary:
      properties:
        id:
          type: string
          format: uuid
          title: Id
        slug:
          type: string
          title: Slug
        name:
          type: string
          title: Name
        industry:
          anyOf:
            - type: string
            - type: 'null'
          title: Industry
        region:
          anyOf:
            - type: string
            - type: 'null'
          title: Region
        lifecycle_state:
          type: string
          title: Lifecycle State
        share_onboarding_outputs:
          type: boolean
          title: Share Onboarding Outputs
        created_at:
          type: string
          format: date-time
          title: Created At
        updated_at:
          type: string
          format: date-time
          title: Updated At
        model_route:
          anyOf:
            - type: string
            - type: 'null'
          title: Model Route
        model_trained_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Model Trained At
      type: object
      required:
        - id
        - slug
        - name
        - industry
        - region
        - lifecycle_state
        - share_onboarding_outputs
        - created_at
        - updated_at
      title: TenantSummary
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError

````