End Close Bulk Requests API

The Bulk Requests API from End Close — 4 operation(s) for bulk requests.

OpenAPI Specification

end-close-bulk-requests-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: End Close Bank Account Balances Bulk Requests 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: Bulk Requests
paths:
  /bulk_requests:
    get:
      summary: List bulk requests
      description: Cursor-paginated list of bulk requests in your environment, ordered by `created_at` descending. Filter by data stream, status, or source.
      parameters:
      - in: query
        name: data_stream_key
        schema:
          type: string
        description: Filter to bulk requests targeting this data stream
      - in: query
        name: status
        schema:
          type: string
          enum:
          - pending
          - processing
          - completed
          - failed
          - cancelled
      - in: query
        name: source
        schema:
          type: string
        description: Filter by request source (e.g. `bulk_api`, `csv`, `nacha`)
      - in: query
        name: created_after
        schema:
          type: string
          format: date-time
        description: ISO8601 lower bound on `created_at`
      - in: query
        name: created_before
        schema:
          type: string
          format: date-time
        description: ISO8601 upper bound on `created_at`
      - in: query
        name: cursor
        schema:
          type: string
        description: Opaque cursor returned by a previous call's `next_cursor`. Omit for the first page.
      - in: query
        name: limit
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 50
      responses:
        '200':
          description: Paginated bulk requests
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/BulkRequest'
                  next_cursor:
                    type: string
                    nullable: true
                    description: Pass back as `cursor` to fetch the next page. Null when no more pages.
                  limit:
                    type: integer
        '401':
          description: Unauthorized
        '422':
          description: Invalid `status`, `created_after`, or `created_before`
      tags:
      - Bulk Requests
  /bulk_requests/{id}:
    get:
      summary: Get bulk request status
      description: Poll the status of an asynchronous bulk request. Returns the bulk request payload plus paginated per-row results. Results grow as processing continues, so only non-pending items are included.
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
        description: The bulk request ID returned from POST /records/bulk
      - in: query
        name: limit
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 50
        description: Number of result items to return
      - in: query
        name: offset
        schema:
          type: integer
          default: 0
        description: Pagination offset for result items
      responses:
        '200':
          description: Bulk request payload with paginated results
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BulkRequest'
                - type: object
                  properties:
                    results:
                      type: object
                      properties:
                        data:
                          type: array
                          items:
                            type: object
                            properties:
                              index:
                                type: integer
                                description: Zero-based position in the original request array
                              status:
                                type: string
                                enum:
                                - successful
                                - failed
                                - skipped
                              record_id:
                                type: integer
                                description: ID of the created record. Only present when status is successful
                              error:
                                type: string
                                description: Error message. Only present when status is failed
                        has_more:
                          type: boolean
                        offset:
                          type: integer
        '401':
          description: Unauthorized
        '404':
          description: Bulk request not found
      tags:
      - Bulk Requests
  /bulk_requests/{id}/cancel:
    post:
      summary: Cancel a bulk request
      description: Sets `cancellation_requested_at` so the running job exits cleanly to `cancelled` on its next heartbeat. Idempotent — re-cancelling just bumps the timestamp.
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
      responses:
        '202':
          description: Cancellation requested
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkRequest'
        '401':
          description: Unauthorized
        '404':
          description: Bulk request not found
        '409':
          description: Bulk request is not in a cancellable status (must be `pending` or `processing`)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
      tags:
      - Bulk Requests
  /bulk_requests/{id}/retry:
    post:
      summary: Retry a bulk request
      description: Creates a new bulk request that re-runs only the parent's failed and skipped items. The new request's `parent_bulk_request_id` points at the original.
      parameters:
      - in: path
        name: id
        required: true
        schema:
          type: string
        description: The ID of the failed or cancelled bulk request to retry
      responses:
        '202':
          description: Retry created and enqueued. Returns the **new** bulk request, not the parent.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkRequest'
        '401':
          description: Unauthorized
        '404':
          description: Bulk request not found
        '409':
          description: Bulk request is not in a retryable status (must be `failed` or `cancelled`)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
      tags:
      - Bulk Requests
components:
  schemas:
    BulkRequest:
      type: object
      description: Full bulk request payload, returned by show, list, cancel, and retry endpoints.
      properties:
        id:
          type: integer
        status:
          type: string
          enum:
          - pending
          - processing
          - completed
          - failed
          - cancelled
          description: pending = queued, processing = records being inserted, completed = all rows processed, failed = job errored, cancelled = cancellation honored on a heartbeat
        source:
          type: string
          nullable: true
          description: Origin of the request (e.g. `bulk_api`, `csv`, `nacha`)
        total_items:
          type: integer
        processed_items:
          type: integer
        successful_items:
          type: integer
        failed_items:
          type: integer
        skipped_items:
          type: integer
          description: 'Records skipped due to `on_conflict: skip` matching an existing `external_id`'
        progress:
          type: integer
          description: processed_items / total_items as a percentage (0-100)
        filename:
          type: string
          nullable: true
          description: Original filename for CSV/NACHA uploads. Null for API-submitted requests.
        created_at:
          type: string
          format: date-time
        started_at:
          type: string
          format: date-time
          nullable: true
        completed_at:
          type: string
          format: date-time
          nullable: true
        last_progress_at:
          type: string
          format: date-time
          nullable: true
          description: Heartbeat timestamp from the worker; used to detect stuck jobs
        cancellation_requested_at:
          type: string
          format: date-time
          nullable: true
          description: Set by POST /bulk_requests/{id}/cancel; the worker exits at its next heartbeat
        parsing:
          type: boolean
          description: True while a CSV/NACHA upload is still being parsed (before rows are enqueued)
        stuck:
          type: boolean
          description: True if the request has been `processing` for more than 5 minutes without a heartbeat
        error_message:
          type: string
          nullable: true
        error_details:
          type: object
          additionalProperties: true
          description: Free-form structured error context (e.g. row indices, validation errors)
        parent_bulk_request_id:
          type: integer
          nullable: true
          description: If this request is a retry, the ID of the original (parent) bulk request
        on_conflict:
          type: string
          enum:
          - skip
          - error
          description: Conflict policy applied when an `external_id` already exists in the stream
        data_stream_id:
          type: integer
          nullable: true
          description: Data stream the request targets, when applicable
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY