> ## Documentation Index
> Fetch the complete documentation index at: https://endclose.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bulk create records

> Submit up to 1,000 records for asynchronous processing. Returns immediately with a bulk request ID. Each record is validated and inserted independently, so some records can succeed while others fail. Use the `GET /bulk_requests/{id}` endpoint to poll for results.



## OpenAPI

````yaml /openapi.json post /records/bulk
openapi: 3.1.0
info:
  title: End Close 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: []
paths:
  /records/bulk:
    post:
      summary: Bulk create records
      description: >-
        Submit up to 1,000 records for asynchronous processing. Returns
        immediately with a bulk request ID. Each record is validated and
        inserted independently, so some records can succeed while others fail.
        Use the `GET /bulk_requests/{id}` endpoint to poll for results.
      parameters:
        - in: header
          name: Idempotency-Key
          schema:
            type: string
          description: >-
            Optional idempotency key. If a bulk request with this key already
            exists for your environment, the existing request is returned
            instead of creating a new one.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - records
              properties:
                on_conflict:
                  type: string
                  enum:
                    - skip
                    - error
                  default: skip
                  description: >-
                    How to handle records whose `external_id` already exists in
                    the target stream. `skip` (default) silently skips
                    duplicates and counts them in `skipped_items`. `error`
                    surfaces duplicates as per-row failures. Only applies to
                    records with `external_id` set.
                records:
                  type: array
                  minItems: 1
                  maxItems: 1000
                  items:
                    type: object
                    required:
                      - date
                      - data_stream_key
                      - amount
                      - direction
                    properties:
                      date:
                        type: string
                        format: date
                        description: The date of the record
                      data_stream_key:
                        type: string
                        description: Key of the data stream this record belongs to
                      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 — defaults to `USD` when omitted.**
                          Case-insensitive on input.
                        pattern: ^[A-Za-z]{3}$
                        default: USD
                      direction:
                        type: string
                        enum:
                          - credit
                          - debit
                        description: Whether this is a credit or debit
                      description:
                        type: string
                        description: Optional description
                      external_id:
                        type: string
                        description: Optional external identifier
                      metadata:
                        type: object
                        additionalProperties: true
                        default: {}
                        description: Arbitrary key-value metadata
      responses:
        '202':
          description: Bulk request accepted for processing
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkRequestSummary'
        '400':
          description: Invalid `on_conflict` value
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
        '401':
          description: Unauthorized
        '422':
          description: >-
            Invalid request (e.g. records is not an array, empty, or exceeds
            1,000 items)
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
components:
  schemas:
    BulkRequestSummary:
      type: object
      description: >-
        Summary returned when a bulk request is created or retrieved via
        idempotency key
      properties:
        id:
          type: integer
          description: Unique identifier for the bulk request
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
            - cancelled
          description: Current processing status
        total_items:
          type: integer
          description: Number of records submitted
        processed_items:
          type: integer
          description: Number of records processed so far
        successful_items:
          type: integer
          description: Number of records successfully created
        failed_items:
          type: integer
          description: Number of records that failed
        skipped_items:
          type: integer
          description: >-
            Number of records skipped due to `on_conflict: skip` matching an
            existing `external_id`
        url:
          type: string
          description: Polling URL to check progress (e.g. /v1/bulk_requests/123)
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY

````