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

# Create and assign interviews

> Create and assign one interview per assignee. **Admin only.**

Provide existing project members via `assignee_ids` and/or new people to
invite via `invite_emails` (at least one is required). Invitees are added
as non-admin Contributors. A separate interview is created for each
assignee and the response is the list of created interviews.

`write_scope` defaults to `local`. A `global` write scope requires every
assignee to already be a project admin and cannot be combined with
`invite_emails`.

`scheduled_send_at` delays only the invitation email — interviews are
created and visible in-app immediately. `reminders` configures automatic
chase emails that run until the interview is completed, the cap is
reached, or an admin stops them.

`draft_id` marks this send as consuming a saved interview draft: the
draft is deleted in the same transaction, and its stored title is reused
when the sent topic still matches the draft's.

`interview_type: "guided-interview"` creates guided (multi-topic
deep-dive) conversations structured by `topics` — an ordered list of
`{title, description, skill_id}` seeded as conversation-scoped topics at
send time (at least one is required). With a `draft_id`, the draft's
type is authoritative (immutable), while payload `topics` override the
draft's saved list — the form may hold unsaved edits at send time.
Guided sends reject `questions`: the topics structure the conversation,
so must-cover points belong in the `topic` (focus) text.

`campaign_id` / `campaign_name` group the created interviews under an
interview campaign (e.g. a workshop wave). `campaign_id` picks an existing
campaign; `campaign_name` reuses the project's campaign with that name
(case-insensitive) or creates it. When both are absent the send falls back
to the consumed draft's saved campaign; an explicit `campaign_id: null`
clears a drafted campaign.




## OpenAPI

````yaml /api-reference/openapi-full.yaml post /projects/{project_id}/interviews/assign/
openapi: 3.0.3
info:
  title: Clarifeye Platform API — Full API Documentation
  description: >
    Complete REST API reference for the Clarifeye Platform.


    Documents every endpoint exposed by the platform — the public surface plus

    the advanced surface: pipeline customization (extraction flows, pipeline

    runs, warehouse tables, document tag/metadata configuration), the pre-MCP

    AI surface (agent settings, playground conversations, conversation-scoped

    feedback views, notifications), and the impersonation header. New AI

    integrations should consume knowledge via MCP rather than the

    conversation/agent-settings endpoints documented here.


    ## Authentication

    All endpoints require authentication. Include the Authorization header in
    every request using either format:

    - `Authorization: Token <token_key>`

    - `Authorization: Bearer <token_key>`


    ## Organization API Key Authentication

    The user-provisioning endpoints authenticate with an **org-scoped API key**
    instead of a user token:

    - `Authorization: Api-Key <key>`


    The key is minted internally by Clarifeye (not self-service) and is scoped
    to a single

    organization — it can only act on the organization whose UUID matches the
    `{id}` in the

    request path. The email domains a key may pre-create accounts for are
    configured by

    Clarifeye on the organization (`allowed_provisioning_domains`). Once you
    have a key and

    your domains are set, call `POST /organizations/{id}/provision-user/` to
    pre-create users

    and `POST /organizations/{id}/deprovision-user/` to remove them.


    ## Impersonation


    Certain endpoints support user impersonation for creating or listing data on
    behalf of other users.

    This is useful for integrating external systems that need to attribute
    actions to specific users.


    **Header:** `X-Impersonate-Email`


    **Required Permission:** `CAN_IMPERSONATE_OTHER_USERS` (contact Clarifeye to
    enable this permission)


    **Behavior:**

    - If the header is provided and the impersonator has the required
    permission, the action is performed as the target user

    - If the target user is not found, the request proceeds as the original
    authenticated user

    - If the target user does not have access to the project, the request
    proceeds as the original authenticated user

    - If the impersonator lacks the `CAN_IMPERSONATE_OTHER_USERS` permission,
    the header is ignored
  version: 1.0.0
  contact:
    name: Clarifeye Support
servers:
  - url: https://eu.app.clarifeye.ai/api/v1
    description: EU
  - url: https://us.app.clarifeye.ai/api/v1
    description: US
security:
  - BearerAuth: []
  - TokenAuth: []
tags:
  - name: Users
    description: Manage users within a project
  - name: Invitations
    description: Manage project invitations
  - name: Documents
    description: Manage documents within a project
  - name: Agent Settings
    description: Manage AI agent configurations
  - name: Conversations
    description: Create and interact with AI-powered conversations
  - name: Interviews
    description: Assign and review structured interview conversations
  - name: Feedback
    description: >-
      Submit and review feedback — standalone (content-only), agent-submitted
      (MCP), or linked to a conversation message
  - name: Tools
    description: Execute configured AI tools with custom parameters
  - name: Tables
    description: Perform CRUD operations on warehouse tables
  - name: Notifications
    description: Manage project-scoped notifications for users
  - name: Extraction Flows
    description: >-
      Manage extraction flows (auto-sync DAGs) — list, run, inspect statistics,
      update, and publish
  - name: Object Extractors
    description: |
      Extract structured data (instances of a Pydantic model) from chunks or
      blocks of documents. Update auto-creates a new `ObjectExtractorVersion`
      when version-bearing fields change.
  - name: Tag Extractors
    description: |
      Apply hierarchical metadata tags to chunks or documents using an LLM.
      Update auto-creates a new `TagExtractorVersion` when version-bearing
      fields change.
  - name: Chunks Extractors
    description: |
      Segment parsed documents into chunks for downstream processing.
      Update auto-creates a new `ChunksExtractorVersion` when version-bearing
      fields change.
  - name: Parsing Extractors
    description: |
      Convert source documents to text blocks via the parsing pipeline.
      Update auto-creates a new `ParsingExtractorVersion` when version-bearing
      fields change.
  - name: Document Filter Extractors
    description: |
      Restrict a downstream pipeline branch to documents matching a filter.
      Update auto-creates a new version when the filter changes.
  - name: Chunk Tag Filter Extractors
    description: |
      Restrict a downstream pipeline branch to chunks carrying specific tags.
      Update auto-creates a new version when the filter changes.
  - name: Document Tag Extractors
    description: |
      Apply a flat set of metadata tags to each document. Update auto-creates
      a new version when version-bearing fields change.
  - name: Tag Alerts Extractors
    description: |
      Run LLM-based alerts over already-extracted tag rows. Update auto-creates
      a new version when version-bearing fields change.
  - name: Object Alerts Extractors
    description: >
      Run LLM-based alerts over already-extracted object rows. Update
      auto-creates

      a new version when version-bearing fields change.
  - name: Imported Object Extractors
    description: |
      Hold objects imported from an external system (rather than extracted by
      an LLM). Useful for hydrating the warehouse with data produced outside
      the platform.
  - name: Pipeline Runs
    description: >-
      Inspect pipeline runs queued by extraction flows or other pipeline
      triggers — list runs and fetch the details/status of a single run
  - name: User Provisioning
    description: >
      Pre-create and de-provision org users via an org-scoped API key

      (`Authorization: Api-Key <key>`). The organization is resolved from the
      key.
  - name: Organization API Keys
    description: >
      Superuser management of org-scoped provisioning API keys. Minting and
      revoking

      are superuser-only; org admins can list/retrieve/reveal their own org's
      keys.
  - name: Design System Templates
    description: Reference/example files attached to a design template.
paths:
  /projects/{project_id}/interviews/assign/:
    post:
      tags:
        - Interviews
      summary: Create and assign interviews
      description: >
        Create and assign one interview per assignee. **Admin only.**


        Provide existing project members via `assignee_ids` and/or new people to

        invite via `invite_emails` (at least one is required). Invitees are
        added

        as non-admin Contributors. A separate interview is created for each

        assignee and the response is the list of created interviews.


        `write_scope` defaults to `local`. A `global` write scope requires every

        assignee to already be a project admin and cannot be combined with

        `invite_emails`.


        `scheduled_send_at` delays only the invitation email — interviews are

        created and visible in-app immediately. `reminders` configures automatic

        chase emails that run until the interview is completed, the cap is

        reached, or an admin stops them.


        `draft_id` marks this send as consuming a saved interview draft: the

        draft is deleted in the same transaction, and its stored title is reused

        when the sent topic still matches the draft's.


        `interview_type: "guided-interview"` creates guided (multi-topic

        deep-dive) conversations structured by `topics` — an ordered list of

        `{title, description, skill_id}` seeded as conversation-scoped topics at

        send time (at least one is required). With a `draft_id`, the draft's

        type is authoritative (immutable), while payload `topics` override the

        draft's saved list — the form may hold unsaved edits at send time.

        Guided sends reject `questions`: the topics structure the conversation,

        so must-cover points belong in the `topic` (focus) text.


        `campaign_id` / `campaign_name` group the created interviews under an

        interview campaign (e.g. a workshop wave). `campaign_id` picks an
        existing

        campaign; `campaign_name` reuses the project's campaign with that name

        (case-insensitive) or creates it. When both are absent the send falls
        back

        to the consumed draft's saved campaign; an explicit `campaign_id: null`

        clears a drafted campaign.
      operationId: assignInterviews
      parameters:
        - $ref: '#/components/parameters/ProjectId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                assignee_ids:
                  type: array
                  description: >-
                    UUIDs of existing project members to interview (must be
                    tech/contributor members).
                  items:
                    type: string
                    format: uuid
                invite_emails:
                  type: array
                  description: >-
                    Email addresses of people to invite on the fly as non-admin
                    Contributors and assign an interview.
                  items:
                    type: string
                    format: email
                topic:
                  type: string
                  description: >-
                    The interview focus. Used to auto-name the interview and
                    seed its first question.
                write_scope:
                  type: string
                  description: >-
                    Whether interview edits stay local to the conversation or
                    write to the shared knowledge store.
                  enum:
                    - local
                    - global
                  default: local
                focused_mode:
                  type: boolean
                  default: false
                  description: >
                    Simplified interview: recipients open the distraction-free
                    full-page

                    chat instead of the app. When a `draft_id` is set, defaults
                    to the

                    draft's value.
                questions:
                  type: array
                  description: >
                    Optional specific topics or questions (max 10). Clara weaves
                    them naturally

                    into the open interview and covers each before closing the
                    topic.
                  items:
                    type: string
                language:
                  type: string
                  nullable: true
                  description: >
                    ISO language code (e.g. `fr`) the interview must be
                    conducted in. Null

                    adapts to each recipient's own preferred language. When a
                    `draft_id` is

                    set and this field is absent, defaults to the draft's value.
                    Unknown

                    codes are rejected (400).
                custom_message:
                  type: string
                  description: >-
                    Optional note from the assigner; replaces the default
                    invitation email copy.
                scheduled_send_at:
                  type: string
                  format: date-time
                  nullable: true
                  description: >-
                    Optional future time to send the invitation email (in-app
                    visibility stays immediate).
                reminders:
                  type: object
                  description: Automatic reminder settings (disabled by default).
                  properties:
                    enabled:
                      type: boolean
                      default: false
                    start_after_days:
                      type: integer
                      minimum: 1
                      maximum: 30
                      default: 2
                    interval_days:
                      type: integer
                      minimum: 1
                      maximum: 30
                      default: 3
                    max_count:
                      type: integer
                      minimum: 1
                      maximum: 10
                      default: 3
                interview_type:
                  type: string
                  enum:
                    - interview
                    - guided-interview
                  default: interview
                  description: >
                    Conversation type to create. Ignored when `draft_id` is set
                    (the

                    draft's type is authoritative).
                topics:
                  type: array
                  description: >
                    Guided interviews only: the ordered topics the interview
                    walks

                    through (max 12, at least one required for guided sends).
                    Overrides

                    a consumed draft's saved topics when provided.
                  items:
                    $ref: '#/components/schemas/GuidedInterviewTopic'
                draft_id:
                  type: string
                  format: uuid
                  nullable: true
                  description: >
                    Optional id of a saved interview draft this send consumes.
                    Rejected

                    (400) when the draft no longer exists (already sent or
                    deleted).
                campaign_id:
                  type: string
                  format: uuid
                  nullable: true
                  description: >
                    Existing campaign to group the created interviews under
                    (must belong

                    to the project). Absent falls back to the consumed draft's
                    saved

                    campaign; an explicit null clears a drafted campaign. Wins
                    over

                    `campaign_name` when both are sent.
                campaign_name:
                  type: string
                  description: >
                    Campaign to group the created interviews under, by name:
                    reuses the

                    project's campaign with that name (case-insensitive) or
                    creates it.
            example:
              assignee_ids:
                - 3fa85f64-5717-4562-b3fc-2c963f66afa6
              invite_emails:
                - newperson@example.com
              topic: Q4 planning and roadmap review
              write_scope: local
              focused_mode: false
              questions:
                - How do you weigh team vs. market vs. traction?
              custom_message: We're building a shared playbook — your instincts are the point.
              reminders:
                enabled: true
                start_after_days: 2
                interval_days: 3
                max_count: 3
      responses:
        '201':
          description: Interviews created and assigned
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Interview'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  parameters:
    ProjectId:
      name: project_id
      in: path
      required: true
      description: UUID of the project
      schema:
        type: string
        format: uuid
  schemas:
    GuidedInterviewTopic:
      type: object
      description: >
        One ordered topic of a guided interview. `skill_id` identifies a topic
        backed by a

        built-in skill from the standard guide and round-trips through edits:
        when editing

        and resending default-guide topics, preserve the `skill_id` values you
        received so

        the topics keep their skill-backed interview depth. Omit `skill_id` for
        hand-added

        custom topics, which are driven by their own title/description text.
      required:
        - title
      properties:
        title:
          type: string
          maxLength: 200
        description:
          type: string
        skill_id:
          type: string
          nullable: true
    Interview:
      type: object
      description: A structured interview conversation, including its full transcript.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          nullable: true
          description: Interview title (auto-generated from the topic when not provided).
        created_by:
          type: string
          format: uuid
          readOnly: true
          description: UUID of the user who created the interview.
        created_by_email:
          type: string
          format: email
          nullable: true
          readOnly: true
          description: >-
            Email of the user who created the interview (the importer, for
            imported interviews).
        type:
          type: string
          description: >
            Conversation type: "interview" (standard mono-topic),
            "guided-interview"

            (a multi-topic deep-dive whose ordered topics come from the sent
            draft or

            assign payload; its focus text lives in

            `type_additional_parameters.interview_focus`), or
            "imported-interview"

            (a read-only transcript of an interview recorded outside the
            platform,

            created via the import-transcript endpoint).
        type_additional_parameters:
          type: object
          description: Free-form parameters associated with the conversation type.
        chat_history:
          type: array
          description: Ordered list of transcript entries (messages, tool calls, etc.).
          items:
            type: object
        chat_memory:
          type: object
          description: Assistant memory state accumulated over the conversation.
        local_documents:
          type: array
          readOnly: true
          description: >
            Files uploaded during this interview (ordered by upload time). Only
            the id and

            name are included; resolve a fresh signed download URL via the
            project-level

            local-documents detail endpoint.
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
              name:
                type: string
        assigned_to:
          type: string
          format: uuid
          nullable: true
          readOnly: true
          description: >-
            UUID of the assigned user (null while a pending invite has not yet
            joined).
        assigned_by:
          type: string
          format: uuid
          nullable: true
          readOnly: true
          description: UUID of the user who created the assignment.
        assigned_to_email:
          type: string
          format: email
          nullable: true
          readOnly: true
          description: >-
            Assignee email, falling back to the invite email for not-yet-joined
            invitees.
        assigned_by_email:
          type: string
          format: email
          nullable: true
          readOnly: true
        is_pending_invite:
          type: boolean
          readOnly: true
          description: True when assigned to someone who has not yet joined the project.
        invite_config:
          allOf:
            - $ref: '#/components/schemas/InterviewInviteConfig'
          nullable: true
          readOnly: true
        interview_focus:
          type: object
          nullable: true
          readOnly: true
          description: >
            The seeded interview topic and optional specific questions, for
            rendering the

            in-chat intro card. Null for non-interviews and interviews without a
            topic.

            For guided interviews this is read from

            `type_additional_parameters.interview_focus` (they have no focus
            issue).
          properties:
            topic:
              type: string
            questions:
              type: array
              items:
                type: string
        topics:
          type: array
          readOnly: true
          description: >
            Guided interviews only: the ordered topic agenda seeded at send
            time,

            with per-topic progress. Empty for every other interview type.
          items:
            type: object
            properties:
              title:
                type: string
              description:
                type: string
              status:
                type: string
                enum:
                  - open
                  - resolved
                  - dismissed
                description: |
                  "open" while the topic still has to be covered; "resolved" or
                  "dismissed" once it no longer is. The interview auto-completes
                  when no topic is left open.
              skill_id:
                type: string
                nullable: true
                description: >-
                  Standard-guide skill backing the topic; null for custom
                  topics.
        campaign:
          allOf:
            - $ref: '#/components/schemas/InterviewCampaignRef'
          nullable: true
          readOnly: true
          description: Campaign this interview belongs to; null for ad hoc interviews.
        campaign_id:
          type: string
          format: uuid
          nullable: true
          writeOnly: true
          description: >
            PATCH-only: move the interview to another campaign of the project
            (or

            null to remove it from its campaign), so past interviews can be

            re-bucketed retroactively.
        is_first_interview:
          type: boolean
          readOnly: true
          description: >
            True while the requesting user has never started an assigned
            interview in this

            project. Drives the intro card's expanded "how it works" explainer.
        import_info:
          allOf:
            - $ref: '#/components/schemas/ImportedInterviewInfo'
          nullable: true
          readOnly: true
        conversation_summary:
          type: string
          readOnly: true
          description: >-
            Background-generated summary of the conversation ("" until
            generated).
        status:
          type: string
          nullable: true
          readOnly: true
          enum:
            - pending
            - in_progress
            - completed
          description: Null for imported interviews until their transcript parse completes.
        write_scope:
          type: string
          enum:
            - local
            - global
          description: >-
            Whether edits stay local to the conversation or write to the shared
            knowledge store.
        focused_mode:
          type: boolean
          readOnly: true
          description: >
            Simplified interview: when true the invite opens the
            distraction-free

            full-page chat (/interview/<project>/<conversation>) instead of the
            app.

            Set at assign time; never changed afterwards.
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
    InterviewInviteConfig:
      type: object
      description: >
        Invitation-email customization and reminder schedule for an assigned
        interview.

        Null for self-assigned interviews, non-interview conversations, and
        interviews

        created before this feature existed.
      readOnly: true
      properties:
        custom_message:
          type: string
          description: >-
            The assigner's note; replaces the default invitation email copy when
            set.
        scheduled_send_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            When the invitation email is (or was) due to be sent. Null means it
            was sent immediately.
        invitation_email_sent_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            When the invitation email actually went out; null while a scheduled
            send is still pending.
        reminders_enabled:
          type: boolean
        reminder_start_after_days:
          type: integer
        reminder_interval_days:
          type: integer
        reminder_max_count:
          type: integer
        reminders_sent:
          type: integer
          description: Automatic reminders sent so far (manual reminders are not counted).
        next_reminder_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            When the next automatic reminder is due; null when none is
            scheduled.
        reminders_stopped:
          type: boolean
          description: True once an admin/assigner stopped the schedule via stop-reminders.
    InterviewCampaignRef:
      type: object
      description: Nested campaign reference carried by interviews and drafts.
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
    ImportedInterviewInfo:
      type: object
      description: >
        Parse-pipeline state of an imported external transcript (interviews of
        type

        "imported-interview"). Null on every other interview type. The raw
        pasted

        transcript is never returned — the parsed `chat_history` is the
        transcript.
      properties:
        import_status:
          type: string
          enum:
            - parsing
            - ready
            - failed
          description: >
            "parsing" while the async parse runs (transcript not yet readable),

            "ready" once chat_history holds the speaker-labeled turns (status
            becomes

            "completed"), "failed" when parsing errored (use retry-import).
        participants:
          type: array
          description: >-
            Participant names (importer-supplied or inferred from the
            transcript).
          items:
            type: string
        interview_date:
          type: string
          format: date
          nullable: true
          description: Date the conversation happened (importer-supplied or inferred).
        error:
          type: string
          nullable: true
          description: Failure detail when import_status is "failed".
    Error:
      type: object
      properties:
        error:
          type: string
          description: Error message
      example:
        error: User not found
    ValidationError:
      type: object
      additionalProperties:
        type: array
        items:
          type: string
      example:
        email:
          - This field is required.
  responses:
    BadRequest:
      description: Bad request - invalid parameters or request body
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/Error'
              - $ref: '#/components/schemas/ValidationError'
    Unauthorized:
      description: Unauthorized - missing or invalid authentication
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Authentication credentials were not provided.
    Forbidden:
      description: Forbidden - insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: You do not have permission to perform this action.
    NotFound:
      description: Not found - resource does not exist
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Not found.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: 'Use Authorization: Bearer <token>'
    TokenAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'Use Authorization: Token <token>'

````