End Close Reconciliation Exceptions API

The Reconciliation Exceptions API from End Close — 2 operation(s) for reconciliation exceptions.

OpenAPI Specification

end-close-reconciliation-exceptions-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: End Close Bank Account Balances Reconciliation Exceptions API
  description: REST API is used to interact with the End Close platform.
  license:
    name: MIT
  version: 1.0.0
servers:
- url: https://api.endclose.com/v1
security:
- ApiKeyAuth: []
tags:
- name: Reconciliation Exceptions
paths:
  /reconciliation_exceptions:
    get:
      summary: List reconciliation exceptions
      description: Returns a paginated list of exceptions, optionally filtered by reconciliation or status. Each row includes data-stream metadata and an aggregates summary so you can render a queue without a follow-up request per row.
      parameters:
      - in: query
        name: reconciliation_id
        schema:
          type: string
        description: Filter by reconciliation
      - in: query
        name: status
        schema:
          type: string
          enum:
          - open
          - investigating
          - dismissed
          - resolved
        description: Filter by exception status
      - in: query
        name: limit
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - in: query
        name: offset
        schema:
          type: integer
        description: Pagination offset
      responses:
        '200':
          description: Paginated list of exceptions
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ReconciliationException'
                  has_more:
                    type: boolean
                  offset:
                    type: number
        '401':
          description: Unauthorized
      tags:
      - Reconciliation Exceptions
    post:
      summary: Create a reconciliation exception
      description: Create an exception for a reconciliation and data stream. Only one `open` or `investigating` exception can exist per (data stream, reconciliation) pair at a time. `title` defaults to `"{data_stream_name} — overdue records"`, and `status` defaults to `open`. The system automatically creates exceptions via its overdue sweeper — use this endpoint when you want to open one manually.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - reconciliation_id
              - data_stream_id
              properties:
                reconciliation_id:
                  type: string
                  description: Reconciliation the exception belongs to
                data_stream_id:
                  type: string
                  description: Data stream the exception is scoped to. Must belong to the reconciliation.
                title:
                  type: string
                description:
                  type: string
                status:
                  type: string
                  enum:
                  - open
                  - investigating
                  - dismissed
                  - resolved
                  default: open
      responses:
        '201':
          description: Exception created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationException'
        '401':
          description: Unauthorized
        '404':
          description: Reconciliation or data stream not found
        '422':
          description: Validation failed, or a duplicate open/investigating exception already exists for this (data stream, reconciliation)
      tags:
      - Reconciliation Exceptions
  /reconciliation_exceptions/{id}:
    get:
      summary: Retrieve a reconciliation exception
      description: Returns the exception with assignees, comments, recent investigation sessions, `aggregates` for the entire overdue slice, and `filtered_aggregates` restricted to the supplied filter query parameters. All filter parameters are optional.
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      - in: query
        name: amount_min
        schema:
          type: integer
        description: Include records with signed amount >= amount_min (cents)
      - in: query
        name: amount_max
        schema:
          type: integer
        description: Include records with signed amount <= amount_max (cents)
      - in: query
        name: date_from
        schema:
          type: string
          format: date
        description: Include records with transaction date >= date_from
      - in: query
        name: date_to
        schema:
          type: string
          format: date
        description: Include records with transaction date <= date_to
      - in: query
        name: direction
        schema:
          type: string
          enum:
          - debit
          - credit
        description: Include only debits (amount < 0) or credits (amount > 0)
      - in: query
        name: counterparty
        schema:
          type: string
        description: Case-insensitive substring match on record description
      - in: query
        name: age_bucket
        schema:
          type: string
          enum:
          - lt_7d
          - 7_30d
          - 30_90d
          - gt_90d
        description: Convenience age filter on time since `overdue_at`
      responses:
        '200':
          description: Exception retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationException'
        '401':
          description: Unauthorized
        '404':
          description: Exception not found
      tags:
      - Reconciliation Exceptions
    patch:
      summary: Update a reconciliation exception
      description: Update the title, description, or status of an exception.
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                description:
                  type: string
                status:
                  type: string
                  enum:
                  - open
                  - investigating
                  - dismissed
                  - resolved
      responses:
        '200':
          description: Exception updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationException'
        '404':
          description: Exception not found
      tags:
      - Reconciliation Exceptions
    delete:
      summary: Delete a reconciliation exception
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      responses:
        '204':
          description: Exception deleted successfully
        '404':
          description: Exception not found
      tags:
      - Reconciliation Exceptions
components:
  schemas:
    ReconciliationException:
      type: object
      required:
      - title
      - reconciliation_id
      - data_stream_id
      description: A reconciliation exception represents unmatched overdue records that need human attention. Exceptions are scoped to a (reconciliation, data_stream) tuple and managed by the sweeper job — record membership is computed on read from the set of unmatched records whose `overdue_at` has passed.
      properties:
        id:
          type: integer
        reconciliation_id:
          type: integer
          description: The reconciliation this exception belongs to
        reconciliation_name:
          type: string
          description: Name of the parent reconciliation
        data_stream_id:
          type: integer
          description: The data stream this exception is scoped to
        data_stream_name:
          type: string
          description: Human-readable name of the scoped data stream
        data_stream_key:
          type: string
          description: Immutable key of the scoped data stream
        title:
          type: string
        description:
          type: string
        status:
          type: string
          enum:
          - open
          - investigating
          - dismissed
          - resolved
          default: open
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        opened_at:
          type: string
          format: date-time
          nullable: true
          description: When the exception most recently transitioned into an open state. Distinct from `created_at` so reopening is tracked cleanly.
        closed_at:
          type: string
          format: date-time
          nullable: true
          description: When the exception most recently transitioned into a resolved or dismissed state. Cleared on reopen.
        assignees:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
              workos_user_id:
                type: string
        decimal_places:
          type: integer
          description: Number of decimal places (2 for USD)
          default: 2
        aggregates:
          allOf:
          - $ref: '#/components/schemas/ExceptionAggregates'
          description: Whole-exception aggregates over the current unmatched overdue slice.
        filtered_aggregates:
          allOf:
          - $ref: '#/components/schemas/ExceptionAggregates'
          description: Aggregates restricted to the filter query parameters. Equals `aggregates` when no filter is supplied. Only present on the show response.
        comments:
          type: array
          description: Comments on this exception, oldest first
          items:
            type: object
            properties:
              id:
                type: integer
              body:
                type: string
              author_workos_id:
                type: string
              mentions:
                type: array
                items:
                  type: integer
                description: User IDs mentioned in the comment
              created_at:
                type: string
                format: date-time
        investigation:
          allOf:
          - $ref: '#/components/schemas/AgentInvestigationSession'
          nullable: true
          description: The most recent agent investigation session for this exception, if any.
        investigation_sessions:
          type: array
          description: Up to the five most recent investigation sessions, newest first. Exceptions may accumulate multiple sessions as the overdue set evolves.
          items:
            $ref: '#/components/schemas/AgentInvestigationSession'
    AgentInvestigationSession:
      type: object
      description: An agent-run investigation into an exception's record slice.
      properties:
        id:
          type: integer
        status:
          type: string
          description: Investigation status (e.g. pending, running, completed, failed)
        outcome:
          type: string
          nullable: true
          enum:
          - match_found
          - no_match
          - needs_review
          - null
          description: Standardized outcome of a completed investigation. `match_found` = confident candidate matches; `no_match` = thorough search returned nothing; `needs_review` = candidates found but signals are weak. Null when the session is not yet completed or failed.
        recommendation_text:
          type: string
          nullable: true
          description: Agent's recommendation once the investigation completes
        confidence_score:
          type: number
          nullable: true
          description: Agent confidence in its recommendation (0.0-1.0)
        candidate_records_searched:
          type: integer
          nullable: true
          description: Number of candidate records the agent evaluated
        suggested_record_ids:
          type: array
          nullable: true
          items:
            type: integer
          description: Records the agent suggests linking to this exception
        filter_params:
          type: object
          nullable: true
          additionalProperties: true
          description: Filter parameters the session was scoped to, if any. Matches the filter shape on `GET /reconciliation_exceptions/{id}`.
        completed_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time
    ExceptionAggregates:
      type: object
      description: Summary statistics for the (filtered) set of unmatched overdue records behind an exception.
      properties:
        record_count:
          type: integer
          description: Number of matching overdue unmatched records
        total_amount:
          type: integer
          description: Sum of signed amounts in cents (debits are negative)
        debit_count:
          type: integer
          description: Count of records with amount < 0
        debit_sum:
          type: integer
          description: Sum of debit amounts in cents (non-positive)
        credit_count:
          type: integer
          description: Count of records with amount > 0
        credit_sum:
          type: integer
          description: Sum of credit amounts in cents (non-negative)
        avg_age_days:
          type: number
          description: Average age in days since each record's `overdue_at`
        oldest_at:
          type: string
          format: date-time
          nullable: true
          description: Transaction date of the oldest record in the slice
        newest_at:
          type: string
          format: date-time
          nullable: true
          description: Transaction date of the newest record in the slice
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY