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

# List cases

> **Who can call it:** Any signed-in member of the workspace.

Newest first. `source=partner` keeps only the cases filed through the Partner API (those with a `reference`). Send `X-Sahl-Environment: sandbox` or `production` (or the `environment` query parameter) to choose the workspace. Without it, no environment filter is applied. `production` is refused with 403 `production_requires_paid_plan` when the subscription is cancelled or suspended.

**Auth:** dashboard session (`Authorization: Bearer <access token>`). Not available with a partner API key.



## OpenAPI

````yaml /openapi-console.json get /v1/cases
openapi: 3.1.0
info:
  title: Sahl Console API
  version: 0.1.0
  description: >-
    **Used by the Sahl console. Not available with partner API keys. Contact
    Sahl if you need programmatic access.**


    These are the routes the Sahl console calls with a signed-in user's session.
    They are documented so that a developer or a workspace admin can see what
    the console does, with the real request and response models. They are
    **not** part of the [Partner API](/api-reference/introduction): an API key
    is refused here (401), there is no try-it, and the shapes can change with
    the console.


    Authentication: `Authorization: Bearer <access token>`, the JWT the console
    gets from `POST /v1/auth/login` (30 minutes; renewed with `POST
    /v1/auth/refresh`, refresh token valid 7 days). There is no cookie. The role
    of the user is read from the user's record on every call, not from the
    token. Every call is scoped to the workspace of the user.


    Common answers: 401 (no or bad session), 403 `Insufficient permissions`
    (role), 422 (validation), 429 (100 requests per minute and IP). Error bodies
    have the same three shapes as the Partner API: see [Errors](/errors).
servers:
  - url: https://app.sahlfinancial.com/api
    description: Console host. Same host as the Partner API.
security:
  - dashboardSession: []
tags:
  - name: Bank connections
    description: Simulated in the Sandbox; 409 `bank_connect_unavailable` elsewhere.
  - name: Cases
    description: Client files that group documents, a score and a decision.
  - name: Documents
    description: Upload, status, result and download.
  - name: Webhooks
    description: Manage the endpoints that receive events.
  - name: API keys
    description: Create, rotate and revoke the keys used with the Partner API.
  - name: Scoring policies
    description: Weights and thresholds of the credit score.
  - name: Flows
    description: Verification flows (graphs) and their simulation.
paths:
  /v1/cases:
    get:
      tags:
        - Cases
      summary: List cases
      description: >-
        **Who can call it:** Any signed-in member of the workspace.


        Newest first. `source=partner` keeps only the cases filed through the
        Partner API (those with a `reference`). Send `X-Sahl-Environment:
        sandbox` or `production` (or the `environment` query parameter) to
        choose the workspace. Without it, no environment filter is applied.
        `production` is refused with 403 `production_requires_paid_plan` when
        the subscription is cancelled or suspended.


        **Auth:** dashboard session (`Authorization: Bearer <access token>`).
        Not available with a partner API key.
      operationId: listCases
      parameters:
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
            title: Page
        - name: page_size
          in: query
          required: false
          schema:
            type: integer
            maximum: 100
            minimum: 1
            default: 20
            title: Page Size
        - name: status
          in: query
          required: false
          schema:
            anyOf:
              - type: string
                enum:
                  - new
                  - docs_received
                  - identity_verified
                  - bank_connected
                  - scoring
                  - scored
                  - approved
                  - refused
                  - manual_review
                  - expired
              - type: 'null'
            title: Status
        - name: priority
          in: query
          required: false
          schema:
            anyOf:
              - type: string
                enum:
                  - low
                  - medium
                  - high
                  - urgent
              - type: 'null'
            title: Priority
        - name: document_id
          in: query
          required: false
          schema:
            anyOf:
              - type: string
                format: uuid
              - type: 'null'
            title: Document Id
        - name: search
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Search
        - name: source
          in: query
          required: false
          schema:
            anyOf:
              - const: partner
                type: string
              - type: 'null'
            title: Source
        - name: reference
          in: query
          required: false
          schema:
            anyOf:
              - type: string
                maxLength: 255
              - type: 'null'
            title: Reference
        - name: environment
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Environment
        - name: X-Sahl-Environment
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: X-Sahl-Environment
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CaseListResponse'
              example:
                items:
                  - id: 7e3b9a14-2d6c-4c85-b1f0-6a8d4e2c9b37
                    tenant_id: 0b6f5a3e-7c1d-4e0a-9d2f-3a1c5e8b7f10
                    document_id: null
                    applicant_name: Test Client
                    applicant_cin: AB123456
                    borrower_type: private_sector
                    status: new
                    priority: medium
                    score: null
                    risk_level: null
                    eligible_amount: null
                    score_breakdown: null
                    ai_insight: null
                    decision: null
                    decision_at: null
                    decision_by: null
                    decision_note: null
                    assigned_to: null
                    environment: sandbox
                    external_reference: null
                    metadata_json: null
                    created_at: '2026-10-07T09:14:22Z'
                    updated_at: '2026-10-07T09:14:22Z'
                total: 1
                page: 1
                page_size: 20
        '401':
          description: No session, expired token, ended session or inactive account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                detail: Invalid or expired token
        '403':
          description: >-
            The role is not allowed, MFA enrolment is pending, or the
            environment is refused.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                detail: Insufficient permissions
        '422':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                detail:
                  - type: missing
                    loc:
                      - body
                      - bank_code
                    msg: Field required
                    input: {}
        '429':
          description: >-
            More than 100 requests per minute from one IP address. The body has
            no `detail`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
              example:
                code: rate_limit_exceeded
                message: Too many requests. Please slow down.
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait.
components:
  schemas:
    CaseListResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/CaseResponse'
          type: array
        total:
          type: integer
        page:
          type: integer
        page_size:
          type: integer
      type: object
      required:
        - items
        - total
        - page
        - page_size
    Error:
      type: object
      description: >-
        FastAPI error body. `detail` is a string, a list (422), or an object
        with `code` and `message` (extra keys possible).
      properties:
        detail:
          oneOf:
            - type: string
            - items:
                additionalProperties: true
                type: object
              type: array
            - type: object
              additionalProperties: true
              properties:
                code:
                  type: string
                message:
                  type: string
      required:
        - detail
    RateLimitError:
      type: object
      description: Top-level `code` and `message`, no `detail`.
      properties:
        code:
          type: string
        message:
          type: string
      required:
        - code
        - message
    CaseResponse:
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        document_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
        applicant_name:
          anyOf:
            - type: string
            - type: 'null'
        applicant_cin:
          anyOf:
            - type: string
            - type: 'null'
        borrower_type:
          anyOf:
            - type: string
            - type: 'null'
        status:
          type: string
        priority:
          type: string
        score:
          anyOf:
            - type: integer
            - type: 'null'
        risk_level:
          anyOf:
            - type: string
            - type: 'null'
        eligible_amount:
          anyOf:
            - type: integer
            - type: 'null'
        score_breakdown:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
        ai_insight:
          anyOf:
            - type: string
            - type: 'null'
        decision:
          anyOf:
            - type: string
            - type: 'null'
        decision_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
        decision_by:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
        decision_note:
          anyOf:
            - type: string
            - type: 'null'
        assigned_to:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
        environment:
          type: string
        external_reference:
          anyOf:
            - type: string
            - type: 'null'
        metadata_json:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      type: object
      required:
        - id
        - tenant_id
        - document_id
        - applicant_name
        - applicant_cin
        - borrower_type
        - status
        - priority
        - score
        - risk_level
        - eligible_amount
        - score_breakdown
        - ai_insight
        - decision
        - decision_at
        - decision_by
        - decision_note
        - assigned_to
        - environment
        - metadata_json
        - created_at
        - updated_at
  securitySchemes:
    dashboardSession:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        The access token (JWT) of a signed-in console user, from `POST
        /v1/auth/login`. It lasts 30 minutes. It is not an API key: a partner
        API key is refused here. There is no cookie.

````

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