Elasticsearch Bulk Formatter

Turn a JSON array of documents into the newline-delimited body Elasticsearch and OpenSearch expect for the _bulk API — action metadata lines, optional source lines, trailing newline included.

Try:
Bulk NDJSON

About this tool

The Elasticsearch Bulk Formatter builds the exact newline-delimited JSON body used by the Elasticsearch and OpenSearch _bulk APIs. Paste a JSON array of objects, choose the bulk action, and the tool emits compact NDJSON: one action/metadata line per document and, for index, create, and update, one source line after it. The output always ends with the required trailing newline.

Worked example

Input documents:

[{"id":"1","title":"hello"},{"id":"2","title":"world"}]

Options: action index, target _index my-index, ID field id.

Output:

{"index":{"_index":"my-index","_id":"1"}}
{"title":"hello"}
{"index":{"_index":"my-index","_id":"2"}}
{"title":"world"}

The final line in the actual output is followed by \n, so it is safe to save directly as an NDJSON file and send with curl --data-binary.

Options

Limits and edge cases

This tool only shapes the request body. It does not connect to a cluster, validate mappings, chunk large files into upload-size batches, or add per-document routing/version metadata. It errors on invalid JSON, a non-array root, an empty array, a non-object item, and an update or delete action without an _id value. Numeric IDs stay numeric in the metadata line; string IDs stay strings.

FAQ

Why does the output have a blank-looking line at the end?

The _bulk format requires the body to end with a newline. The tool always appends that final \n; many command-line displays make it look like there is an extra blank line, but it is the correct delimiter for Elasticsearch and OpenSearch.

Should I include `_index` in the body or in the URL?

Both patterns are valid. Fill Target _index to write _index on every action line. Leave it blank when you are posting to a URL such as /my-index/_bulk and want the endpoint to supply the default index.

Why is my ID field removed from the source document?

When you set Document ID field, that field is promoted to _id in the action metadata and removed from the source line. This avoids storing a duplicate application ID field unless you explicitly want it. Leave the field blank for index or create if you want Elasticsearch to generate IDs and keep all document fields.

Can this send the bulk request to my cluster?

No. It is intentionally browser-local and offline: it produces the NDJSON body only. Save or copy the result, then send it with your own curl, Kibana Dev Tools, client library, or deployment pipeline.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool elasticsearch-bulk-formatter '[{"id":"1","title":"hello"},{"id":"2","title":"world"}]'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/elasticsearch-bulk-formatter/?documents=%5B%7B%22id%22%3A%221%22%2C%22title%22%3A%22hello%22%7D%2C%7B%22id%22%3A%222%22%2C%22title%22%3A%22world%22%7D%5D&action=index&index=my-index&id_field=id&doc_as_upsert=true

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.