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

# Create API Key

> Mint a role-scoped platform API key, optionally carrying client metadata for row-level security



## OpenAPI

````yaml POST /v2/api-keys
openapi: 3.1.0
info:
  title: TextQL v2 API
  version: '2.0'
  description: >
    REST API for TextQL platform operations. All endpoints require Bearer token
    authentication.
servers:
  - url: https://app.textql.com
security:
  - bearerAuth: []
tags:
  - name: Chat
    description: Create and manage AI chat sessions
  - name: Connectors
    description: List available data connectors
  - name: Playbooks
    description: Create, configure, and run automated playbooks
  - name: Sandcastles
    description: Manage Python sandbox environments for code execution
  - name: Changes
    description: Review, approve, and deny Ontology changes
  - name: API Keys
    description: Mint and revoke scoped platform API keys
paths:
  /v2/api-keys:
    post:
      tags:
        - API Keys
      summary: Create API Key
      description: |
        Mint a platform API key. Every key must be role-scoped: provide either
        `assumedRoles` (role UUIDs the key is limited to) or set
        `inheritAllRoles` to `true`; a request with neither is rejected so a
        key cannot be over-privileged by accident. Non-admin callers may only
        scope keys to roles they already hold, and a key minted by another API
        key may only narrow the parent key's role scope, never widen it.

        By default the key acts as the caller. With `targetMemberId`, the key
        is minted for another member: a human target requires the caller's role
        to hold `api_access_key:delegate`, while a service-account target
        requires `organization:write`. `organization:write` alone is not enough
        for a human target. A delegated key authenticates as the target member,
        always carries full member access so objects shared directly with that
        member stay reachable, may assume a subset of that member's roles, and
        suppresses superadmin elevation; mint it with a short expiry. Holding
        `api_access_key:delegate` is a full impersonation capability.

        `clientId` attaches client metadata to the key. Prefer a JSON object
        string: TQL row-level security exposes it to saved queries as
        `_tql.client_attributes_json.<field>`, which is how one key per
        tenant/end-user enforces scoped data access.

        The bearer secret is returned once, in `key`, and cannot be retrieved
        again.
      operationId: v2.createApiKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateApiKeyRequest'
      responses:
        '201':
          description: The created key. `key` is the bearer secret, shown only once.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateApiKeyResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    CreateApiKeyRequest:
      type: object
      properties:
        expirySeconds:
          type: integer
          description: >-
            Optional TTL in seconds. Omit for a non-expiring key; short-lived
            keys are recommended for per-session embedding flows.
          example: 3600
        assumedRoles:
          type: array
          items:
            type: string
          description: >-
            Role UUIDs to scope the key to. Callers may only specify roles they
            hold; API-key callers may only specify a subset of their own assumed
            roles.
          example:
            - 80de0196-496f-44fe-9d4c-8013b3b44082
        inheritAllRoles:
          type: boolean
          description: >-
            Set to true to inherit all of the creating member's roles. Required
            when assumedRoles is empty.
        name:
          type: string
          description: Optional display name for the key.
          example: acme-session-key
        targetMemberId:
          type: string
          description: >-
            Mint the key for this member instead of the caller. A human target
            requires the caller's role to hold `api_access_key:delegate`;
            `organization:write` alone is denied. A service-account target
            requires `organization:write`. The key authenticates as the target
            member, always carries full member access so the target's direct
            object grants stay reachable, is scoped to that member's roles, and
            suppresses superadmin elevation. Granting `api_access_key:delegate`
            is a full impersonation capability.
        clientId:
          type: string
          description: >-
            Optional client metadata stored on the key. Prefer a JSON object
            string (a JSON-encoded string, not a nested object); TQL row-level
            security reads its fields as `_tql.client_attributes_json.<field>`.
          example: '{"tenant_id": "acme", "user_email": "jane@acme.example"}'
        fullMemberAccess:
          type: boolean
          description: >-
            When true, the key keeps the target member's direct object grants
            alongside its assumed-role grants. A key minted on behalf of a human
            member always carries full member access regardless of this flag.
            For a key acting as the caller or as a service account, false is the
            default and an API-key caller may set it true only when its own key
            already has full member access.
    CreateApiKeyResponse:
      type: object
      properties:
        key:
          type: string
          description: >-
            The full bearer credential. Shown exactly once; store it securely.
            Use as `Authorization: Bearer <key>`.
          example: BEARER_SECRET_SHOWN_ONCE
        api_key:
          $ref: '#/components/schemas/PlatformApiKey'
    PlatformApiKey:
      type: object
      properties:
        id:
          type: string
          description: The key id — use this for revocation, not the bearer secret
          example: 4f0c39a1-7c9e-4a34-9d20-6a1f6f6f2b71
        member_id:
          type: string
          example: 9b2f7a64-11d0-4c1b-8f3e-2f9c5b7f6e10
        name:
          type: string
          example: acme-session-key
        client_id:
          type: string
          example: '{"tenant_id": "acme", "user_email": "jane@acme.example"}'
        assumed_roles:
          type: array
          items:
            type: string
          example:
            - 80de0196-496f-44fe-9d4c-8013b3b44082
        status:
          type: string
          enum:
            - active
            - expired
            - revoked
            - unspecified
          example: active
        created_at:
          type: string
          description: RFC 3339 timestamp
          example: '2026-07-06T19:30:00Z'
        expires_at:
          type: string
          description: RFC 3339 timestamp; absent for non-expiring keys
          example: '2026-07-06T20:30:00Z'
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: Machine-readable error code
              enum:
                - invalid_request
                - unauthenticated
                - permission_denied
                - not_found
                - conflict
                - rate_limit_exceeded
                - internal
                - timeout
                - cancelled
                - execution_failed
                - no_report
            message:
              type: string
              description: Human-readable error message
  responses:
    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: invalid_request
              message: Invalid request body
    Unauthorized:
      description: Missing or invalid authentication
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: unauthenticated
              message: Authentication required
    Forbidden:
      description: Insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: permission_denied
              message: Insufficient permissions
    RateLimited:
      description: Rate limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: rate_limit_exceeded
              message: Rate limit exceeded
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: internal
              message: Internal server error
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key or JWT token

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.