End Close Reconciliations API

The Reconciliations API from End Close — 4 operation(s) for reconciliations.

Business capability
Reconciliation Management BC-1380.70

Operations 8

POST /reconciliations/{reconciliation_id}/records/{record_id}/mark_overdue Mark a record as overdue #
GET /reconciliations List reconciliations #
POST /reconciliations Create a reconciliation #
GET /reconciliations/{id} Retrieve a reconciliation #
PATCH /reconciliations/{id} Update a reconciliation #
DELETE /reconciliations/{id} Delete a reconciliation #
GET /reconciliations/{id}/agent_status Get reconciliation agent status #
PUT /reconciliations/{reconciliation_id}/data_streams/{data_stream_id}/findings Write findings for a data stream's lines #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/end-close:end-close-reconciliations-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

end-close-reconciliations-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: End Close Reconciliations 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: Reconciliations
paths:
  /reconciliations/{reconciliation_id}/records/{record_id}/mark_overdue:
    post:
      summary: Mark a record as overdue
      description: Flags a record as overdue within a specific reconciliation by setting the `overdue_at` timestamp on its reconciliation entry. The reconciliation and record are both named in the path — the subject is the (reconciliation, record) entry, so the same record can be overdue in one reconciliation and matched in another. The record's data stream must be part of the reconciliation. If no entry exists yet for the record and reconciliation, one is created so unmatched records can be flagged as overdue. Records already matched in this reconciliation cannot be marked overdue. Once overdue, the record is picked up by the exceptions sweeper and rolled into the data-stream-scoped exception for that reconciliation.
      parameters:
      - in: path
        name: reconciliation_id
        required: true
        schema:
          type: string
        description: The unique identifier of the reconciliation the record should be marked overdue in
      - in: path
        name: record_id
        required: true
        schema:
          type: string
        description: The unique identifier of the record
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                overdue_at:
                  type: string
                  format: date-time
                  description: When the record should be considered overdue. Defaults to the current time.
      responses:
        '200':
          description: The record's entry in the given reconciliation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationEntry'
        '401':
          description: Unauthorized
        '404':
          description: Record or reconciliation not found
        '409':
          description: Record is already matched in this reconciliation and cannot be marked overdue
        '422':
          description: Record's data stream is not part of the reconciliation, or invalid `overdue_at`
      tags:
      - Reconciliations
      operationId: postReconciliationsByReconciliationIdRecordsByRecordIdMarkOverdue
      x-operation-id-source: derived
  /reconciliations:
    get:
      summary: List reconciliations
      description: Returns a paginated list of reconciliations with their associated data streams, newest first.
      parameters:
      - in: query
        name: cursor
        required: false
        schema:
          type: string
        description: Opaque cursor from a previous response's `next_cursor`. Omit for the first page.
      - in: query
        name: limit
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 50
      responses:
        '200':
          description: Paginated list of reconciliations
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Reconciliation'
                  next_cursor:
                    type: string
                    nullable: true
                    description: Opaque cursor for the next page. Null when no more pages.
                  limit:
                    type: integer
      tags:
      - Reconciliations
      operationId: getReconciliations
      x-operation-id-source: derived
    post:
      summary: Create a reconciliation
      description: Create a new reconciliation with optional side A and side B data stream associations.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - name
              properties:
                name:
                  type: string
                run_type:
                  type: string
                  enum:
                  - continuous
                  - batch
                  default: continuous
                side_a_stream_ids:
                  type: array
                  items:
                    type: string
                  description: IDs of data streams to assign to side A
                side_b_stream_ids:
                  type: array
                  items:
                    type: string
                  description: IDs of data streams to assign to side B
      responses:
        '201':
          description: Reconciliation created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Reconciliation'
        '422':
          description: Validation error
      tags:
      - Reconciliations
      operationId: postReconciliations
      x-operation-id-source: derived
  /reconciliations/{id}:
    get:
      summary: Retrieve a reconciliation
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Reconciliation retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Reconciliation'
        '404':
          description: Reconciliation not found
      tags:
      - Reconciliations
      operationId: getReconciliationsById
      x-operation-id-source: derived
    patch:
      summary: Update a reconciliation
      description: Update reconciliation name, run type, or reassign data streams. If stream IDs are provided, all existing stream associations are replaced.
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                run_type:
                  type: string
                  enum:
                  - continuous
                  - batch
                side_a_stream_ids:
                  type: array
                  items:
                    type: string
                side_b_stream_ids:
                  type: array
                  items:
                    type: string
      responses:
        '200':
          description: Reconciliation updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Reconciliation'
        '404':
          description: Reconciliation not found
      tags:
      - Reconciliations
      operationId: patchReconciliationsById
      x-operation-id-source: derived
    delete:
      summary: Delete a reconciliation
      description: Permanently deletes a reconciliation and all associated rules, matches, and data stream associations.
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      responses:
        '204':
          description: Reconciliation deleted successfully
        '404':
          description: Reconciliation not found
      tags:
      - Reconciliations
      operationId: deleteReconciliationsById
      x-operation-id-source: derived
  /reconciliations/{id}/agent_status:
    get:
      summary: Get reconciliation agent status
      description: Returns the current status of the reconciliation agent, which automatically creates and refines matching rules. The agent runs automatically when records are uploaded or manually matched — no manual triggering is needed.
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
        description: The reconciliation ID
      responses:
        '200':
          description: Agent status
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                    - idle
                    - running
                    - failed
                    description: Current agent status
                  last_run_at:
                    type: string
                    format: date-time
                    nullable: true
                    description: When the agent last ran
                  progress:
                    type: array
                    description: Ordered list of progress steps from the last run
                    items:
                      type: object
                      properties:
                        step:
                          type: string
                        message:
                          type: string
                        at:
                          type: string
                          format: date-time
                  reasoning:
                    type: string
                    nullable: true
                    description: AI reasoning from the last rule analysis
                  rules_count:
                    type: integer
                    description: Number of active rules on this reconciliation
                  unmatched_count:
                    type: integer
                    description: Number of unreconciled records across both sides
        '404':
          description: Reconciliation not found
      tags:
      - Reconciliations
      operationId: getReconciliationsByIdAgentStatus
      x-operation-id-source: derived
  /reconciliations/{reconciliation_id}/data_streams/{data_stream_id}/findings:
    put:
      summary: Write findings for a data stream's lines
      description: The same upsert as `PUT /reconciliation_exceptions/{id}/findings`, for an engine that runs before the sweeper has opened an exception. Opens the exception for the (reconciliation, data stream) pair if none is open, reuses it otherwise, and returns its id with the result.
      parameters:
      - in: path
        name: reconciliation_id
        required: true
        schema:
          type: string
      - in: path
        name: data_stream_id
        required: true
        schema:
          type: string
        description: The data stream whose records the findings are about. Must be part of the reconciliation.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FindingsUpsertRequest'
      responses:
        '200':
          description: Findings written against the open exception
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/FindingsUpsertResult'
                - type: object
                  properties:
                    exception_id:
                      type: string
                      description: The open exception the findings were written to
        '401':
          description: Unauthorized
        '404':
          description: Reconciliation or data stream not found
        '422':
          description: Data stream is not part of the reconciliation, or `findings` is invalid
      tags:
      - Reconciliations
      operationId: putReconciliationsByReconciliationIdDataStreamsByDataStreamIdFindings
      x-operation-id-source: derived
components:
  schemas:
    FindingInput:
      type: object
      required:
      - note
      description: One line of the review as your engine sees it. Identify the record by `record_id` or by `external_id` (resolved within the exception's data stream). `suggestion.record_ids` may be record ids or external ids from either side of the reconciliation; unknown ids reject the finding.
      properties:
        record_id:
          type: string
          description: The record's id. Required unless `external_id` is given.
        external_id:
          type: string
          description: The record's external id within the exception's data stream. Rejected when it matches more than one record.
        looks_right:
          type: boolean
          default: false
          description: '`true` when the line is correct as it stands and only needs the note. These lines can be confirmed in bulk.'
        note:
          type: string
          description: 'One or two plain sentences: what happened to this line and what was checked.'
        category:
          type: string
          nullable: true
          description: A short label for the kind of line, in your own words (e.g. `back-billing`, `monthly minimum`).
        suggestion:
          type: object
          description: What Approve applies. Omit, or use kind `none`, when there is nothing to apply.
          properties:
            kind:
              type: string
              enum:
              - match
              - adjust
              - none
              default: none
              description: '`match`: pair the line with `record_ids` (must balance). `adjust`: pair them and plug the remaining gap with an adjustment carrying `reason`. `none`: nothing to apply.'
            record_ids:
              type: array
              items:
                type: string
              description: Every other record of the proposed match, either side, as record ids or external ids.
            reason:
              type: string
              description: 'For `adjust`: why a gap remains. Becomes the adjustment''s description.'
            text:
              type: string
              description: The sentence shown next to the Approve button.
            difference_cents:
              type: integer
              description: Informational. Recomputed from the records as |side A| − |side B| whenever `record_ids` is given; only kept as sent for a one-sided `adjust`.
        evidence:
          type: array
          description: Quotes that back the note. A quote with a `url` marks the line as checked against a document in the review.
          items:
            type: object
            required:
            - quote
            properties:
              quote:
                type: string
              source:
                type: string
                nullable: true
                description: Where the quote is from, e.g. `Services Agreement, Exhibit B p.19`.
              url:
                type: string
                nullable: true
                description: 'An http(s) link to the document — for a file in End Close, the file''s `url`. End `#page=N` to open a PDF at that page: the review drawer labels the link “Open p.N” and shows the document inline. Other schemes are dropped.'
        precedent:
          type: string
          nullable: true
          description: How the same line was handled before, in one sentence.
        labels:
          type: object
          additionalProperties: true
          description: 'Free-form markers your reviewers care about, e.g. `{"carried_forward": true, "colour": "peach"}`. The review page reads `colour`, `colour_cell` and `carried_forward`; anything else is stored and returned untouched.'
    Record:
      type: object
      required:
      - date
      - data_stream_key
      - amount
      - direction
      properties:
        id:
          type: integer
        amount:
          type: integer
          description: The monetary amount in cents (e.g., 1234 = $12.34)
        currency:
          type: string
          description: Three-letter ISO 4217 currency code (e.g. USD, EUR). **Optional on create — defaults to `USD` when omitted.** Case-insensitive on input; always returned uppercase.
          pattern: ^[A-Za-z]{3}$
          default: USD
        decimal_places:
          type: integer
          description: Number of decimal places for this currency (2 for USD)
          default: 2
        direction:
          type: string
          enum:
          - credit
          - debit
        description:
          type: string
        date:
          type: string
          format: date
        metadata:
          type: object
          additionalProperties: true
          default: {}
        external_id:
          type: string
        data_stream_key:
          type: string
    ReconciliationRun:
      type: object
      description: A single execution of a reconciliation's batch or continuous matching pipeline.
      properties:
        id:
          type: integer
        kind:
          type: string
          enum:
          - batch
          - continuous
        status:
          type: string
          enum:
          - pending
          - running
          - completed
          - failed
        trigger:
          type: string
          enum:
          - manual
          - rule_activated
          - agent
          - record_created
          - ingestion
          description: What initiated this run. `ingestion` runs are queued automatically once an import lands, so rollup (many_to_one) rules apply to the new records.
        total_records:
          type: integer
          description: Total records considered by the run
        processed_records:
          type: integer
          description: Records processed so far
        matched_records:
          type: integer
          description: Records that were matched during the run
        rule_summary:
          type: object
          nullable: true
          description: Per-rule match counts, populated as the run progresses
        progress:
          type: integer
          description: Processing progress as a percentage (0-100)
        started_at:
          type: string
          format: date-time
          nullable: true
        completed_at:
          type: string
          format: date-time
          nullable: true
    DataStream:
      type: object
      required:
      - key
      - name
      properties:
        id:
          type: integer
          description: Unique numeric identifier
        key:
          type: string
          description: Unique immutable identifier
        name:
          type: string
          description: Human readable name
        description:
          type: string
          description: Optional description of the data stream
        type:
          type: string
          description: The type of data stream (e.g. api, csv, stripe, bank_feed)
        program_id:
          type: integer
          nullable: true
        records_count:
          type: integer
          description: Record count from the ClickHouse mirror
    FindingsUpsertRequest:
      type: object
      required:
      - findings
      properties:
        findings:
          type: array
          maxItems: 1000
          items:
            $ref: '#/components/schemas/FindingInput'
    ReconciliationEntry:
      description: A record's entry in one reconciliation. Match status, escalation, and matched records are all scoped to that reconciliation; a record has one entry per reconciliation it participates in. `id` is the record id.
      allOf:
      - $ref: '#/components/schemas/Record'
      - type: object
        properties:
          reconciliation_id:
            type: integer
          reconciliation_name:
            type: string
          status:
            type: string
            enum:
            - reconciled
            - unreconciled
            description: Whether the record is matched in this reconciliation. Read-only.
          escalated:
            type: boolean
            description: Unmatched and past its `overdue_at`.
          overdue_at:
            type: string
            format: date-time
            nullable: true
          matched_records:
            type: array
            description: Records matched with this record in this reconciliation
            items:
              type: object
              properties:
                id:
                  type: integer
                amount:
                  type: integer
                  description: Amount in cents
                currency:
                  type: string
                  description: Three-letter ISO 4217 currency code (e.g. USD, EUR)
                  default: USD
                decimal_places:
                  type: integer
                  default: 2
                direction:
                  type: string
                  enum:
                  - credit
                  - debit
                description:
                  type: string
                date:
                  type: string
                  format: date
                external_id:
                  type: string
                data_stream_key:
                  type: string
                reconciliation_id:
                  type: integer
                  description: The reconciliation in which this match was made
                reconciliation_name:
                  type: string
                  description: Name of the reconciliation in which this match was made
          days_unreconciled:
            type: integer
            nullable: true
            description: Number of days since the record's date. Null when the record is reconciled.
          exception_id:
            type: integer
            nullable: true
            description: Open exception covering this entry's data stream when the entry is escalated. Null otherwise.
    Reconciliation:
      type: object
      required:
      - name
      properties:
        id:
          type: integer
        name:
          type: string
          description: Human readable name for the reconciliation
        run_type:
          type: string
          enum:
          - continuous
          - batch
          default: continuous
        side_a_streams:
          type: array
          items:
            $ref: '#/components/schemas/DataStream'
          description: Data streams on side A of the reconciliation
        side_b_streams:
          type: array
          items:
            $ref: '#/components/schemas/DataStream'
          description: Data streams on side B of the reconciliation
        created_at:
          type: string
          format: date-time
        current_run:
          $ref: '#/components/schemas/ReconciliationRun'
          nullable: true
          description: The currently pending or running batch run, if any
        last_run:
          $ref: '#/components/schemas/ReconciliationRun'
          nullable: true
          description: The most recent completed or failed batch run, if any
    FindingsUpsertResult:
      type: object
      description: 'Each finding is validated on its own, so a batch succeeds partially: `upserted` counts the rows written and `errors` names the rejected ones by position.'
      properties:
        upserted:
          type: integer
        errors:
          type: array
          items:
            type: object
            properties:
              index:
                type: integer
                description: Position of the rejected finding in the request's `findings`.
              record_id:
                type: string
              external_id:
                type: string
              message:
                type: string
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY
x-provenance:
  method: harvested
  publisher: End Close
  source: https://www.endclose.com/docs/openapi.json
  note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
    stamped by stamp-openapi-provenance.py (roadmap#793)