openapi: 3.0.3
info:
  title: Cardamon Client API
  version: "1.10.0"
  description: |
    Authentication: Authorization: Bearer <opaque API key>, scoped to an organisation.
    Timestamps: ISO 8601 (RFC3339) in UTC with Z, e.g. 2025-08-11T11:53:43.474Z.
    
    Regulations walkthrough: call listRegulations to find a regulation, listRegulationVersions to pick a
    version, then listRegulationVersionNodes to page through its provisions in document order.
    Each item contains id, ref, content and status. Content includes the provision's owned
    child text.

    Pagination: limit is the requested maximum page size; count is the number of items returned in
    that page. Follow next_cursor to retrieve the next page. A null next_cursor means the end, even if count equals limit.
    
    Rate limiting: 100 requests/minute per API key endpoints.

servers:
  - url: https://api.cardamon.ai

tags:
  - name: L1 Mappings
  - name: L2 Mappings
  - name: Policies
  - name: Controls
  - name: Companies
  - name: Horizon Scanning
  - name: Regulations

security:
  - bearerAuth: []

paths:
  /v1/companies/{company_id}/l1-mappings:
    get:
      description: List applicable Regulations that are applicable to the Company.
      tags: [L1 Mappings]
      operationId: listL1Mappings
      summary: List L1 mappings for a company
      parameters:
        - name: company_id
          in: path
          required: true
          description: Company ID
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: L1 mappings
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/L1MappingsResponse"

  /v1/companies:
    get:
      description: List Companies for the Organisation bound to the API key
      tags: [Companies]
      operationId: listCompanies
      summary: List companies
      responses:
        "200":
          description: Companies
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompaniesResponse"

  /v1/companies/{company_id}/policy-items:
    get:
      description: List existing company Policy Items
      tags: [Policies]
      operationId: listPolicies
      summary: List policies for a company (including org-wide)
      parameters:
        - name: company_id
          in: path
          required: true
          description: Company ID
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Policies
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyItemsResponse"

  /v1/companies/{company_id}/policy-items/{policy_id}:
    get:
      description: Get an existing company or organisation-wide Policy Item by its Cardamon ID
      tags: [Policies]
      operationId: getPolicy
      summary: Get a policy for a company
      parameters:
        - name: company_id
          in: path
          required: true
          description: Company ID
          schema:
            type: string
            format: uuid
        - name: policy_id
          in: path
          required: true
          description: Cardamon policy item ID
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Policy
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyItem"
        "404":
          description: Policy not found

  /v1/companies/{company_id}/control-items:
    get:
      description: List existing company and organisation-wide Control Items in scope for the requested company
      tags: [Controls]
      operationId: listControls
      summary: List controls for a company
      parameters:
        - name: company_id
          in: path
          required: true
          description: Company ID
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Controls
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ControlItemsResponse"

  /v1/companies/{company_id}/control-items/{control_id}:
    get:
      description: Get an existing company or organisation-wide Control Item by its Cardamon ID
      tags: [Controls]
      operationId: getControl
      summary: Get a control for a company
      parameters:
        - name: company_id
          in: path
          required: true
          description: Company ID
          schema:
            type: string
            format: uuid
        - name: control_id
          in: path
          required: true
          description: Cardamon control ID
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Control
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ControlItem"
        "404":
          description: Control not found

  /v1/mappings/{l1_mapping_id}/l2-mappings:
    get:
      description: List requirements per applicable Regulation
      tags: [L2 Mappings]
      operationId: listL2MappingsForL1
      summary: List flat L2 mappings for an L1 mapping
      parameters:
        - name: l1_mapping_id
          in: path
          required: true
          description: L1 mapping ID
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Flat L2 mappings
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/L2MappingsResponse"

  /v1/horizon-scanning/findings:
    get:
      description: List Horizon Scanning findings for the organisation. Supports filtering by state, type, dates, jurisdiction, regulation, and product.
      tags: [Horizon Scanning]
      operationId: listFindings
      summary: List findings
      parameters:
        - name: company-id
          in: query
          required: false
          description: Filter to specific companies (repeatable). Omit for all org companies.
          schema:
            type: array
            items:
              type: string
              format: uuid
        - name: state
          in: query
          required: false
          schema:
            type: array
            items:
              type: string
              enum: [CREATED, ACTIVE, ARCHIVED, APPROVED, COMPLETED, DELETED]
        - name: type
          in: query
          required: false
          schema:
            type: array
            items:
              type: string
              enum:
                - INDUSTRY_NEWS
                - ENFORCEMENT_ACTION
                - REGULATION_UPDATE
                - GUIDANCE
                - NU_REGULATION
                - NU_REGULATORY_DEVELOPMENT
                - NU_PRESS_NEWS
                - NU_REGULATOR_NEWS
                - NU_SANCTIONS
                - NU_GUIDANCE
        - name: relevant-date-from
          in: query
          required: false
          schema:
            type: string
            format: date-time
        - name: relevant-date-to
          in: query
          required: false
          schema:
            type: string
            format: date-time
        - name: published-date-from
          in: query
          required: false
          schema:
            type: string
            format: date-time
        - name: published-date-to
          in: query
          required: false
          schema:
            type: string
            format: date-time
        - name: jurisdiction
          in: query
          required: false
          schema:
            type: array
            items:
              type: string
        - name: content-id
          in: query
          required: false
          description: Filter findings by content identifier (repeatable). Use to select findings originating from the same content source.
          schema:
            type: array
            items:
              type: string
              format: uuid
        - name: regulation
          in: query
          required: false
          schema:
            type: array
            items:
              type: string
        - name: regulation-group-id
          in: query
          required: false
          description: Filter findings by regulation group (regulation dictionary entry id, repeatable). Only effective when the regulation dictionary feature is enabled for the organisation; otherwise ignored.
          schema:
            type: array
            items:
              type: string
              format: uuid
        - name: product
          in: query
          required: false
          schema:
            type: array
            items:
              type: string
        - name: applicable
          in: query
          required: false
          description: Filter findings by applicability. Omit to return all findings; true returns only applicable findings; false returns only non-applicable findings.
          schema:
            type: boolean
        - name: cursor
          in: query
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            default: 50
            maximum: 200
      responses:
        "200":
          description: Paginated findings list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FindingsListResponse"
        "403":
          description: Forbidden
        "429":
          description: Rate limit exceeded
          headers:
            Retry-After:
              schema:
                type: integer

  /v1/regulations:
    get:
      description: |
        List regulations with at least one available version. `query` is a case-insensitive
        substring match over the regulation title, source URL, short name and English title translation.
        `jurisdiction` is an exact match on the regulation jurisdiction code.
      tags: [Regulations]
      operationId: listRegulations
      summary: List regulations
      parameters:
        - name: query
          in: query
          required: false
          description: Case-insensitive substring match on title, url, short_name and the English title translation. Accepts up to the full title or source URL length.
          schema:
            type: string
            maxLength: 1024
        - name: jurisdiction
          in: query
          required: false
          description: Exact jurisdiction code, for example GB
          schema:
            type: string
            maxLength: 100
        - $ref: "#/components/parameters/PageLimit"
        - $ref: "#/components/parameters/PageCursor"
        - name: sort-by
          in: query
          required: false
          description: "Sort chain of `field` or `field:asc|desc` segments over `title`, `issuer`, `created_at` and `updated_at`. Defaults to `title:asc`."
          schema:
            type: string
            example: "title:asc"
      responses:
        "200":
          description: Regulations
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicRegulationsPage"
        "400":
          $ref: "#/components/responses/InvalidPagination"
        "403":
          $ref: "#/components/responses/Forbidden"
        "422":
          $ref: "#/components/responses/ValidationFailed"
        "429":
          $ref: "#/components/responses/RateLimited"

  /v1/regulations/{regulation_id}:
    get:
      description: Retrieve a single regulation.
      tags: [Regulations]
      operationId: getRegulation
      summary: Get a regulation
      parameters:
        - $ref: "#/components/parameters/RegulationId"
      responses:
        "200":
          description: Regulation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicRegulationItem"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "422":
          $ref: "#/components/responses/ValidationFailed"
        "429":
          $ref: "#/components/responses/RateLimited"

  /v1/regulations/{regulation_id}/versions:
    get:
      description: |
        List the available versions of a regulation. Each version is one stored edition of the document
        and carries the id of its root node.
      tags: [Regulations]
      operationId: listRegulationVersions
      summary: List regulation versions
      parameters:
        - $ref: "#/components/parameters/RegulationId"
        - $ref: "#/components/parameters/PageLimit"
        - $ref: "#/components/parameters/PageCursor"
        - name: sort-by
          in: query
          required: false
          description: "Sort chain of `field` or `field:asc|desc` segments over `effective_date` and `created_at`. Defaults to `effective_date:desc`; versions without an effective date sort last in both directions."
          schema:
            type: string
            example: "effective_date:desc"
      responses:
        "200":
          description: Regulation versions
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicRegulationVersionsPage"
        "400":
          $ref: "#/components/responses/InvalidPagination"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "422":
          $ref: "#/components/responses/ValidationFailed"
        "429":
          $ref: "#/components/responses/RateLimited"

  /v1/regulations/{regulation_id}/versions/{version_id}:
    get:
      description: Retrieve a single regulation version.
      tags: [Regulations]
      operationId: getRegulationVersion
      summary: Get a regulation version
      parameters:
        - $ref: "#/components/parameters/RegulationId"
        - $ref: "#/components/parameters/RegulationVersionId"
      responses:
        "200":
          description: Regulation version
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicRegulationVersionItem"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "422":
          $ref: "#/components/responses/ValidationFailed"
        "429":
          $ref: "#/components/responses/RateLimited"

  /v1/regulations/{regulation_id}/versions/{version_id}/nodes:
    get:
      description: |
        Page through the provisions of a regulation version. Ascending `position` is document order.
        Each provision includes its owned child text. Nested provisions are returned as separate items
        and are not duplicated in their parent's content. Standalone headings, structural containers
        and provisions whose assembled content is empty or whitespace-only are omitted before pagination.
        Original positions are preserved, so gaps are expected.
      tags: [Regulations]
      operationId: listRegulationVersionNodes
      summary: List regulation version nodes
      parameters:
        - $ref: "#/components/parameters/RegulationId"
        - $ref: "#/components/parameters/RegulationVersionId"
        - $ref: "#/components/parameters/PageLimit"
        - $ref: "#/components/parameters/PageCursor"
        - name: sort-by
          in: query
          required: false
          description: "Sort chain of `field` or `field:asc|desc` segments over `position`, `created_at` and `updated_at`. Defaults to `position:asc`."
          schema:
            type: string
            example: "position:asc"
      responses:
        "200":
          description: Regulation version nodes
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicRegulationNodesPage"
        "400":
          $ref: "#/components/responses/InvalidPagination"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "422":
          $ref: "#/components/responses/ValidationFailed"
        "429":
          $ref: "#/components/responses/RateLimited"

  /v1/regulations/{regulation_id}/versions/{version_id}/nodes/{node_id}:
    get:
      description: Retrieve a single assembled provision of a regulation version. Returns 404 for structural nodes or provisions without text.
      tags: [Regulations]
      operationId: getRegulationVersionNode
      summary: Get a regulation version node
      parameters:
        - $ref: "#/components/parameters/RegulationId"
        - $ref: "#/components/parameters/RegulationVersionId"
        - name: node_id
          in: path
          required: true
          description: Regulation node ID
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Regulation version node
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicRegulationNodeItem"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "422":
          $ref: "#/components/responses/ValidationFailed"
        "429":
          $ref: "#/components/responses/RateLimited"

components:
  parameters:
    RegulationId:
      name: regulation_id
      in: path
      required: true
      description: Regulation ID
      schema:
        type: string
        format: uuid
    RegulationVersionId:
      name: version_id
      in: path
      required: true
      description: Regulation version ID
      schema:
        type: string
        format: uuid
    PageLimit:
      name: limit
      in: query
      required: false
      description: Maximum number of items to return
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 50
    PageCursor:
      name: cursor
      in: query
      required: false
      description: Opaque cursor from a previous response. Valid only for the same path, filters and sort chain.
      schema:
        type: string

  responses:
    Forbidden:
      description: Missing, invalid or revoked API key, or the key lacks the required scope
    NotFound:
      description: No such resource is available
    ValidationFailed:
      description: Request validation failed, for example an out-of-range limit or an invalid UUID
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ValidationErrorResponse"
    InvalidPagination:
      description: Unsupported sorting or an invalid cursor
    RateLimited:
      description: The API key has exhausted the shared allowance for regulation requests

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: opaque

  schemas:
    ValidationErrorResponse:
      type: object
      properties:
        detail:
          type: array
          items:
            type: object
            properties:
              loc:
                type: array
                items:
                  type: string
              msg:
                type: string
              type:
                type: string

    PublicRegulationsPage:
      type: object
      required: [items, limit, count, next_cursor]
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/PublicRegulationItem"
        limit:
          type: integer
        count:
          type: integer
          description: Number of items in this page, not a total count
        next_cursor:
          type: string
          nullable: true

    PublicRegulationVersionsPage:
      type: object
      required: [items, limit, count, next_cursor]
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/PublicRegulationVersionItem"
        limit:
          type: integer
        count:
          type: integer
          description: Number of items in this page, not a total count
        next_cursor:
          type: string
          nullable: true

    PublicRegulationNodesPage:
      type: object
      required: [items, limit, count, next_cursor]
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/PublicRegulationNodeItem"
        limit:
          type: integer
        count:
          type: integer
          description: Number of items in this page, not a total count
        next_cursor:
          type: string
          nullable: true

    PublicRegulationItem:
      type: object
      required: [id, title, short_name, geo_jurisdiction, issuer, url]
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        short_name:
          type: string
          nullable: true
        geo_jurisdiction:
          type: string
          description: Jurisdiction code
        issuer:
          type: string
          nullable: true
        url:
          type: string
          nullable: true
          description: Public HTTP(S) source location of the regulation, when one is known

    PublicRegulationVersionItem:
      type: object
      required: [id, regulation_id, effective_date, url]
      properties:
        id:
          type: string
          format: uuid
        regulation_id:
          type: string
          format: uuid
        effective_date:
          type: string
          format: date
          nullable: true
          description: Effective date of this edition. Null when the source does not state one; it is not inferred from the regulation.
        url:
          type: string
          nullable: true
          description: Public HTTP(S) source location of this edition, when one is known

    PublicRegulationNodeItem:
      type: object
      required: [id, ref, content, status]
      properties:
        id:
          type: string
          format: uuid
          description: Identifies the node within its version. Node ids are not stable across versions.
        ref:
          type: string
          nullable: true
          description: Source reference of the node, for example an article number
        content:
          type: string
          description: Original provision text and its owned descendant text, joined with newlines in document order. Existing whitespace and formatting are preserved. Nested provisions are separate items. No Markdown conversion or rendering is applied.
        status:
          type: string
          enum: [ACTIVE, DELETED, FUTURE]
          description: Status of the provision in the source document. DELETED means the source marks the provision as repealed or removed; it says nothing about this API.

    CompaniesResponse:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/CompanyItem"

    CompanyItem:
      type: object
      required: [id, name, descriptor]
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        descriptor:
          $ref: "#/components/schemas/CompanyDescriptorView"

    CompanyDescriptorView:
      type: object
      required: [industry, legal_form, services, licences, locations, notes]
      properties:
        industry:
          type: string
        legal_form:
          type: string
        services:
          type: array
          items:
            type: object
            required: [name, description]
            properties:
              name:
                type: string
              description:
                type: string
                nullable: true
        licences:
          type: array
          items:
            type: object
            required: [name, description]
            properties:
              name:
                type: string
              description:
                type: string
                nullable: true
        locations:
          type: array
          items:
            type: string
            description: ISO 3166-1 alpha-2
        notes:
          type: string
          nullable: true

    L1MappingsResponse:
      type: object
      properties:
        items:
          type: array
          items: { $ref: "#/components/schemas/L1Mapping" }
    PolicyItemsResponse:
      type: object
      required: [items]
      properties:
        items:
          type: array
          items: { $ref: "#/components/schemas/PolicyItem" }

    PolicyItem:
      description: Policy item - excerpt from a Policy document
      type: object
      required:
        [id, external_id, name, description, type, state, document_version_id, created_at, created_date]
      properties:
        id:
          type: string
          format: uuid
          description: Cardamon policy item identifier
        external_id:
          type: string
          nullable: true
          description: Identifier of the source policy document in the external system; null for Cardamon-only policies
        name:
          type: string
        description:
          type: string
        type:
          type: string
          enum: [PROVIDED, AI, EXTRACTED]
        state:
          type: string
          enum: [CREATED, REJECTED, APPROVED, DELETED]
        document_version_id:
          type: string
          format: uuid
          nullable: true
          description: Cardamon document version containing this policy item; null when the item is not document-backed
        created_at:
          type: string
          format: date-time
          description: ISO 8601 UTC creation timestamp
        created_date:
          type: string
          format: date-time
          readOnly: true
          description: Deprecated alias of created_at

    ControlItemsResponse:
      type: object
      required: [items]
      properties:
        items:
          type: array
          items: { $ref: "#/components/schemas/ControlItem" }

    ControlItem:
      description: Control item - excerpt from a Control document
      type: object
      required: [id, external_id, name, description, type, origin, created_at, created_date]
      properties:
        id:
          type: string
          format: uuid
          description: Cardamon control identifier
        external_id:
          type: string
          nullable: true
          description: Identifier of the control in the external system; null for Cardamon-only controls
        name:
          type: string
        description:
          type: string
        type:
          type: string
          enum: [COMPANY, EXTRACTED, AI]
          deprecated: true
          description: Deprecated alias of origin
        origin:
          type: string
          enum: [COMPANY, EXTRACTED, AI]
        created_at:
          type: string
          format: date-time
          description: ISO 8601 UTC creation timestamp
        created_date:
          type: string
          format: date-time
          readOnly: true
          description: Deprecated alias of created_at
    Error:
      description: Standard error object
      type: object
      required: [code, message]
      properties:
        code:
          type: string
          description: Machine-readable error code
          example: unauthorized
        message:
          type: string
          description: Human-readable error message
          example: Invalid or missing token

    RegulationSummary:
      description: Minimal regulation details included with L1 mappings
      type: object
      required: [id, title, url, geo_jurisdiction]
      properties:
        id:
          type: string
          format: uuid
          description: Regulation identifier
        title:
          type: string
          description: Regulation title
        url:
          type: string
          format: uri
          description: Canonical regulation URL
        geo_jurisdiction:
          type: string
          description: Jurisdiction/region code

    L1Mapping:
      description: Applicability decision for a Regulation at the Company level
      type: object
      required: [id, company_id, applicable, explanation, created_date, regulation]
      properties:
        id:
          type: string
          format: uuid
          description: L1 mapping identifier
        company_id:
          type: string
          format: uuid
          description: Company identifier
        applicable:
          type: boolean
          description: Whether the regulation is applicable to the company
        explanation:
          type: string
          description: Reasoning behind applicability decision
        created_date:
          type: string
          format: date-time
          description: ISO 8601 UTC with Z
        regulation:
          $ref: "#/components/schemas/RegulationSummary"

    ItemType:
      description: Type of regulatory item based
      type: string
      enum: [CONTEXTUAL, GUIDELINE, OBLIGATION]

    PolicyAssignment:
      description: Policy item linked to the L2 mapping with reasoning
      type: object
      required: [id, external_id, type, reason]
      properties:
        id:
          type: string
          format: uuid
          description: Policy identifier
        external_id:
          type: string
          nullable: true
          description: Identifier of the source policy document in the external system; null for Cardamon-only policies
        type:
          type: string
          enum: [PROVIDED, AI, EXTRACTED]
        reason:
          type: string
          nullable: true
          description: Why the policy is linked

    ControlAssignment:
      description: Control item linked to the L2 mapping with reasoning
      type: object
      required: [id, external_id, type, reason]
      properties:
        id:
          type: string
          format: uuid
          description: Control identifier
        external_id:
          type: string
          nullable: true
          description: Identifier of the control in the external system; null for Cardamon-only controls
        type:
          type: string
          enum: [COMPANY, EXTRACTED, AI]
        reason:
          type: string
          nullable: true
          description: Why the control is linked

    ObligationAssignment:
      description: Obligation linked to the L2 mapping with reasoning
      type: object
      required: [id]
      properties:
        id:
          type: string
          format: uuid
          description: Obligation identifier
        reason:
          type: string
          nullable: true
          description: Why the obligation is linked

    RiskTag:
      description: Risk tag linked to the L2 mapping with its resolved classification names
      type: object
      required: [id, name]
      properties:
        id:
          type: string
          format: uuid
          description: Risk tag identifier
        name:
          type: string
          description: Primary risk tag classification
        sub_name:
          type: string
          nullable: true
          description: Secondary risk tag classification; null when the tag has no sub-classification
        reason:
          type: string
          nullable: true
          description: Why the risk tag is linked

    RiskTagFieldLabels:
      description: Account-specific display labels for risk tag attributes
      type: object
      required: [name, sub_name]
      properties:
        name:
          type: string
          description: Display label for RiskTag.name
        sub_name:
          type: string
          description: Display label for RiskTag.sub_name

    FieldLabels:
      description: Display labels for fields, resolved from organisation terminology with the same defaults as the UI
      type: object
      required: [risk_tags]
      properties:
        risk_tags:
          $ref: "#/components/schemas/RiskTagFieldLabels"

    L2MappingsResponse:
      type: object
      properties:
        items:
          type: array
          items: { $ref: "#/components/schemas/L2Mapping" }
        field_labels:
          $ref: "#/components/schemas/FieldLabels"

    L2Mapping:
      description: Applicability data for a Regulation Article Item (requirement)
      type: object
      required:
        [id, reference, applicable, explanation, original_text, item_type, risk_tags, policies, controls]
      properties:
        id:
          type: string
          format: uuid
          description: L2 mapping identifier
        reference:
          type: string
          description: Article item reference
        applicable:
          type: boolean
          description: Whether the requirement is applicable
        explanation:
          type: string
          description: Reasoning behind applicability
        original_text:
          type: string
          description: Original article item text
        simplified_text:
          type: string
          nullable: true
          description: Simplified article item text
        item_type:
          $ref: "#/components/schemas/ItemType"
          description: Item type
        type_reasoning:
          type: string
          nullable: true
          description: Reasoning for item type
        risk_score_id:
          type: string
          format: uuid
          nullable: true
          description: Identifier of computed risk score
        risk_score_reasoning:
          type: string
          nullable: true
          description: Reasoning for risk score
        risk_tags:
          type: array
          description: Linked risk tags with resolved primary and optional secondary classification names
          items: { $ref: "#/components/schemas/RiskTag" }
        policies:
          type: array
          description: Linked policies with reasons
          items: { $ref: "#/components/schemas/PolicyAssignment" }
        controls:
          type: array
          description: Linked controls with reasons
          items: { $ref: "#/components/schemas/ControlAssignment" }
        obligations:
          type: array
          nullable: true
          description: Linked obligations with reasons
          items: { $ref: "#/components/schemas/ObligationAssignment" }
        path:
          type: array
          description: Path to the requirement from the root
          items: { type: string }

    FindingSummaryItem:
      type: object
      required:
        - id
        - company_id
        - content_id
        - state
        - finding_type
        - title
        - summary
        - relevant_date
        - created_date
        - applicable
        - post_to_slack
        - jurisdictions
        - regulations
        - products
        - impact
        - urgency
        - assignments
      properties:
        id:
          type: string
          format: uuid
        company_id:
          type: string
          format: uuid
          description: Company this finding belongs to
        company_name:
          type: string
          nullable: true
          description: Display name of the company. Null when the company relation is not loaded.
        content_id:
          type: string
          format: uuid
          description: >-
            Stable identifier for the underlying regulatory content.
            Findings across different companies with the same content_id
            originate from the same content source. Use to deduplicate or group findings.
        slug:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        finding_type:
          type: string
          description: >-
            Type of finding. Known values: INDUSTRY_NEWS, ENFORCEMENT_ACTION,
            REGULATION_UPDATE, GUIDANCE, NU_REGULATION, NU_REGULATORY_DEVELOPMENT,
            NU_PRESS_NEWS, NU_REGULATOR_NEWS, NU_SANCTIONS, NU_GUIDANCE.
        title:
          type: string
        summary:
          type: string
        source_url:
          type: string
          nullable: true
        source_organisation:
          type: string
          nullable: true
        relevant_date:
          type: string
          format: date
        regulation_effective_date:
          type: string
          format: date
          nullable: true
        published_date:
          type: string
          format: date-time
          nullable: true
        created_date:
          type: string
          format: date-time
        applicable:
          type: boolean
        post_to_slack:
          type: boolean
          description: Whether this finding is selected for Slack posting
        jurisdictions:
          type: array
          items:
            $ref: "#/components/schemas/JurisdictionItem"
        regulations:
          type: array
          items:
            $ref: "#/components/schemas/RegulationReference"
        products:
          type: array
          items:
            type: string
        impact:
          type: string
          nullable: true
        urgency:
          type: string
          nullable: true
        implementation_necessary:
          type: string
          nullable: true
          enum:
            - "YES"
            - "NO"
            - "TBD"
          description: Whether the regulation requires implementation action. Optional org-level extension. Null when not set.
        regulation_change_type:
          type: string
          nullable: true
          enum:
            - "NEW"
            - "AMENDMENT"
          description: Whether the regulation is foundational (NEW) or amends an existing regulation (AMENDMENT). Optional org-level extension. Null when not set.
        assignments:
          type: array
          description: People assigned to this finding.
          items:
            $ref: "#/components/schemas/AssignmentItem"

    AssignmentItem:
      type: object
      required:
        - assignment_type
        - email
        - external_id
      properties:
        assignment_type:
          type: string
          description: >-
            Assignment type for this person on the finding
            (for example ASSIGNEE, RESPONSIBLE, ACCOUNTABLE, REPORTER).
            Available types are organisation-specific.
        email:
          type: string
          description: Email address of the assigned user.
        external_id:
          type: string
          nullable: true
          description: >-
            An external identifier for the user, supplied by your organisation when a custom
            user synchronisation is configured. Null otherwise.

    JurisdictionItem:
      type: object
      required:
        - name
        - code
      properties:
        name:
          type: string
          description: Human-readable jurisdiction name
        code:
          type: string
          description: ISO 3166-1 alpha-2 for countries, ISO 3166-2 for subdivisions, or supranational entity code

    RegulationReference:
      type: object
      required:
        - regulation_id
        - name
        - l1_mapping_id
      properties:
        regulation_id:
          type: string
          format: uuid
          nullable: true
        name:
          type: string
        l1_mapping_id:
          type: string
          format: uuid
          nullable: true
        regulation_group_id:
          type: string
          format: uuid
          nullable: true
          description: Regulation dictionary entry id (regulation group); only populated when the regulation dictionary feature is enabled for the organisation
        rationale:
          type: string
          nullable: true
          description: Rationale for the regulation's relevance to the finding; only populated when the regulation dictionary feature is enabled for the organisation
        relation:
          type: string
          nullable: true
          enum: [SUBJECT, RELEVANT, REFERENCE]
          description: How the regulation relates to the finding, derived from relevance; only populated when the regulation dictionary feature is enabled for the organisation

    FindingsListResponse:
      type: object
      required: [items]
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/FindingSummaryItem"
        next_cursor:
          type: string
          nullable: true
