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

# Run HASP's native chat completion for the caller's org

> Streams by default, or returns the assembled response.



## OpenAPI

````yaml /openapi/v1.json post /ai/chat
openapi: 3.1.0
info:
  title: HASP AI API
  version: '2026-07-12'
  description: >-
    The HASP Public AI API is the regulated-AI substrate for healthcare and
    other

    regulated industries — identity, policy, audit, compliance, and PHI handling

    for AI inference, exposed via two surfaces:


    - **Native (`/v1/ai/*`)**: HASP-native chat with full event taxonomy, run
    lifecycle,
      and PHI metadata.
    - **Anthropic-compat (`/v1/messages`)**: Drop-in replacement for
    `@anthropic-ai/sdk` —
      change only `baseURL`. All Gateway compliance checks (BAA, credits, PHI policy) apply.

    All requests require an API key (`Authorization: Bearer
    hasp_api_live_<key>`). See

    [Authentication](https://docs.usehasp.com/ai-api/authentication) for key
    management.
servers:
  - url: https://api.usehasp.com/v1
    description: Production
security:
  - http: []
paths:
  /ai/chat:
    post:
      tags:
        - Chat
      summary: Run HASP's native chat completion for the caller's org
      description: Streams by default, or returns the assembled response.
      operationId: v1.ai.chat
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChatRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                anyOf:
                  - type: object
                    properties:
                      success:
                        type: boolean
                      data:
                        type: object
                        properties:
                          id:
                            type: string
                          model: {}
                          role:
                            type: string
                            const: assistant
                          content:
                            type: array
                            items:
                              anyOf:
                                - type: object
                                  properties:
                                    type:
                                      type: string
                                      const: text
                                    text:
                                      type: string
                                  required:
                                    - type
                                    - text
                                - type: object
                                  properties:
                                    type:
                                      type: string
                                      const: tool_use
                                    id:
                                      anyOf:
                                        - type: string
                                        - type: string
                                          enum:
                                            - ''
                                    name:
                                      anyOf:
                                        - type: string
                                        - type: string
                                          enum:
                                            - ''
                                    input:
                                      anyOf:
                                        - type: string
                                        - type: array
                                          items:
                                            type: string
                                          minItems: 0
                                          maxItems: 0
                                          additionalItems: false
                                  required:
                                    - type
                                    - id
                                    - name
                                    - input
                          stop_reason:
                            type: string
                          usage:
                            anyOf:
                              - type: string
                              - type: array
                                items:
                                  type: string
                                minItems: 0
                                maxItems: 0
                                additionalItems: false
                        required:
                          - id
                          - model
                          - role
                          - content
                          - stop_reason
                          - usage
                      meta:
                        type: object
                        properties:
                          request_id:
                            type:
                              - string
                              - 'null'
                        required:
                          - request_id
                    required:
                      - success
                      - data
                      - meta
                  - type: string
            text/event-stream:
              schema:
                type: string
          headers:
            Transfer-Encoding:
              required: true
              schema:
                type: string
                enum:
                  - chunked
        '401':
          description: Bearer token is missing, malformed, or revoked.
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  error:
                    type: authentication
                    code: INVALID_API_KEY
                    message: Bearer token is missing, malformed, or revoked.
                    param: null
                    details: null
                    retryable: false
                    request_id: 01JQREQ7XZQK5N6PZ1VVXHYB8T
                  meta:
                    request_id: 01JQREQ7XZQK5N6PZ1VVXHYB8T
        '403':
          $ref: '#/components/responses/AuthorizationException'
        '404':
          description: ''
          content:
            application/json:
              schema:
                anyOf:
                  - type: object
                    properties:
                      success:
                        type: boolean
                      error:
                        type: object
                        properties:
                          type:
                            type: string
                          code:
                            type: string
                          message:
                            type: string
                            const: Conversation not found.
                          param:
                            type: string
                            const: conversation_id
                          details:
                            type:
                              - string
                              - 'null'
                          retryable:
                            type: boolean
                          request_id:
                            type: string
                        required:
                          - type
                          - code
                          - message
                          - param
                          - details
                          - retryable
                          - request_id
                      meta:
                        type: object
                        properties:
                          request_id:
                            type: string
                        required:
                          - request_id
                      errors:
                        type: string
                    required:
                      - success
                      - error
                      - meta
                      - errors
                  - type: object
                    properties:
                      error:
                        type: object
                        properties:
                          message:
                            type: string
                            const: Conversation not found.
                          type:
                            type: string
                            enum:
                              - authentication_error
                              - permission_error
                              - invalid_request_error
                              - not_found_error
                              - rate_limit_error
                              - api_error
                          param:
                            type: string
                            const: conversation_id
                          code:
                            type: string
                          hasp_code:
                            type: string
                          hasp_details:
                            type: string
                        required:
                          - message
                          - type
                          - param
                          - code
                          - hasp_code
                          - hasp_details
                    required:
                      - error
                  - type: object
                    properties:
                      type:
                        type: string
                        const: error
                      error:
                        type: object
                        properties:
                          type:
                            type: string
                            enum:
                              - authentication_error
                              - permission_error
                              - invalid_request_error
                              - not_found_error
                              - rate_limit_error
                              - api_error
                              - overloaded_error
                          message:
                            type: string
                            const: Conversation not found.
                          hasp_code:
                            type: string
                          hasp_request_id:
                            type: string
                          hasp_details:
                            type: string
                        required:
                          - type
                          - message
                          - hasp_code
                          - hasp_request_id
                          - hasp_details
                    required:
                      - type
                      - error
        '422':
          $ref: '#/components/responses/ValidationException'
        '429':
          description: >-
            Rate limit exceeded. Retry after the window indicated by
            `Retry-After`.
          content:
            application/json:
              schema:
                type: object
                example:
                  success: false
                  error:
                    type: rate_limited
                    code: RATE_LIMITED
                    message: >-
                      Rate limit exceeded (per-key, per-org, or daily cap,
                      depending on which limiter tripped).
                    param: null
                    details: null
                    retryable: true
                    request_id: 01JQREQ7XZQK5N6PZ1VVXHYB8T
                  meta:
                    request_id: 01JQREQ7XZQK5N6PZ1VVXHYB8T
          headers:
            Retry-After:
              description: Seconds until the rate-limit window resets.
              schema:
                type: integer
            X-RateLimit-Limit:
              description: The request cap for the current window.
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Requests remaining in the current window (0 on a 429).
              schema:
                type: integer
            X-RateLimit-Reset:
              description: Unix timestamp when the window resets.
              schema:
                type: integer
        '500':
          description: |-
            Generic message — matches the streaming path's SSE error event,
            which never surfaces the raw exception message (may carry
            upstream/provider details) to the caller.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        const: INFERENCE_UPSTREAM_FAILURE
                      message:
                        type: string
                        const: Inference stream failed.
                    required:
                      - code
                      - message
                required:
                  - success
                  - error
components:
  schemas:
    ChatRequest:
      type: object
      description: >-
        Validates POST /v1/ai/chat per PRD §05-public-api.


        HASP-509: extended from a single-turn `message` field to a full superset
        —

        `messages[]` history (same content-block dialect Anthropic-compat uses,
        so

        AnthropicMessagesRequestBuilder is reused verbatim for both), `tools`,
        and

        the full cross-provider parameter set (`top_p`/`top_k`/`tool_choice`/

        `metadata`/`stop_sequences`). `message` (singular) is preserved as
        shorthand

        for a single user-turn request — exactly one of `message`/`messages`
        must

        be present.
      properties:
        message:
          type: string
          maxLength: 100000
        model:
          type:
            - string
            - 'null'
          maxLength: 100
        conversation_id:
          type:
            - string
            - 'null'
          description: |-
            Either a bare ULID (the pre-existing passthrough tag) or a
            `conv_`-prefixed id naming a server-owned conversation
            (ADR-AHK8YT). Validated as a pattern rather than `ulid` so the
            prefixed form is not rejected before the controller can resolve
            it; which of the two it is decides whether the call is stateful.
          pattern: ^(conv_)?[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$
        stream:
          type:
            - boolean
            - 'null'
        store:
          type:
            - boolean
            - 'null'
        system:
          type:
            - string
            - 'null'
          maxLength: 10000
        tool_choice:
          type:
            - string
            - 'null'
          description: |-
            InferenceRequest's canonical vocabulary directly: 'auto'|'any'|
            'none'|<tool name> — no compat-surface wire shape to normalize.
        top_p:
          type:
            - number
            - 'null'
          minimum: 0
          maximum: 1
        top_k:
          type:
            - integer
            - 'null'
          minimum: 1
        provider_extensions:
          type:
            - array
            - 'null'
          description: |-
            Escape hatch for provider-specific wire keys the canonical
            fields above don't (yet) model — see ADR-ZP99PX.
          items:
            type: string
        stop_sequences:
          type:
            - array
            - 'null'
          items:
            type: string
        metadata:
          type: object
          properties:
            user_id:
              type:
                - string
                - 'null'
              maxLength: 255
        subject:
          type: object
          description: |-
            PRD-phi-reidentification-map §8: contextual subject binding for the
            audit row fidelity layer. Optional everywhere — when present, both
            type and id must be set (rule `required_with` on each side).
          properties:
            type:
              type:
                - string
                - 'null'
              maxLength: 64
            id:
              type:
                - string
                - 'null'
              maxLength: 256
        on_behalf_of:
          type: object
          description: |-
            Asserted end-user identity: which user of your application took
            this action. Recorded on the audit chain as an assertion made by
            your integration — HASP does not verify it, and it is never
            shown to the model. Distinct from `subject`, which names who or
            what the action is about. `id` is your stable identifier for
            the person; `display` is an optional human-readable name shown
            to audit reviewers. Supported for API-key credentials only.
          properties:
            id:
              type: string
              maxLength: 256
            display:
              type:
                - string
                - 'null'
              maxLength: 256
        messages:
          type: array
          items:
            type: object
            properties:
              role:
                type: string
                enum:
                  - user
                  - assistant
              content:
                type: string
                description: >-
                  Same content-block dialect as MessagesRequest
                  (Anthropic-compat):

                  plain string, or an array of text/tool_use/tool_result blocks.
            required:
              - role
              - content
          minItems: 1
        tools:
          type:
            - array
            - 'null'
          description: |-
            App-domain tool shape — no wire-format translation needed since
            this is HASP's own surface, not a compat passthrough.
          items:
            type: object
            properties:
              name:
                type: string
              description:
                type:
                  - string
                  - 'null'
              input_schema:
                type:
                  - object
                  - 'null'
                properties:
                  type:
                    type:
                      - string
                      - 'null'
      title: ChatRequest
  responses:
    AuthorizationException:
      description: Authorization error
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                description: Error overview.
            required:
              - message
    ValidationException:
      description: Validation error
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                description: Errors overview.
              errors:
                type: object
                description: A detailed description of each field that failed validation.
                additionalProperties:
                  type: array
                  items:
                    type: string
            required:
              - message
              - errors
  securitySchemes:
    http:
      type: http
      scheme: bearer

````