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.
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
- Documents JSON array — a JSON array of objects. Each object becomes one operation.
- Bulk action —
index,create,update, ordelete. - Target
_index— written into every metadata line. Leave blank when you plan to POST to/<index>/_bulkand want the URL to supply the index. - Document ID field — the field whose value becomes
_id; that field is removed from the emitted source document. It is required forupdateanddeleteand optional forindexandcreate. - doc_as_upsert — for
update, adds"doc_as_upsert": truebeside"doc"so missing documents are inserted from the partial document. It is ignored for other actions.
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=trueMachine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
