End Close Bulk Requests API
The Bulk Requests API from End Close — 4 operation(s) for bulk requests.
The Bulk Requests API from End Close — 4 operation(s) for bulk requests.
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