What a merchant module must send to NitroSearch, and what NitroSearch will make of it.
This repository is generated. Do not edit it by hand — open an issue instead, or the next regeneration will silently revert your change.
What is here
-
kit/— an optional, dependency-free PHP 7.4+ package for building payloads. Vendor it; do not Composer-require it. Its currency-exponent table is generated from the backend's own, so it cannot disagree with the system it sends to. Seekit/README.md. -
schema/ingest-batch.v1.schema.json— JSON Schema (2020-12) for the body ofPOST /v1/ingest/batch. Generated from the validation rules the endpoint enforces, not transcribed from a document, so it cannot describe an endpoint that does not exist. -
fixtures/— conformance cases. Each carries awirepayload and theexpected_documentNitroSearch produces from it. Every expected value was produced by running the real pipeline, so a case cannot assert behaviour the backend does not have. Run them in your own CI: no secrets, no network, no account required. -
fixtures/product-usd-two-decimal-places.json -
fixtures/product-jpy-zero-decimal-places.json -
fixtures/product-kwd-three-decimal-places.json -
fixtures/product-chf-two-decimal-places.json -
fixtures/product-legacy-no-price-exponent.json -
fixtures/product-legacy-sales-rank.json -
fixtures/product-variants-fold-into-one-object.json -
fixtures/product-attribute-spellings-merge.json -
fixtures/product-visible-absent-fails-closed.json -
fixtures/product-unsafe-url-is-dropped.json -
fixtures/content-page-with-excerpt.json -
fixtures/content-object-type-absent-means-product.json
The five things that catch adapter authors out
- Money is integer minor units, and you must declare the exponent.
19.99is1999withprice_exponent: 2. Yen is1000withprice_exponent: 0. Omitting the exponent means "I scaled by 100 whatever the currency", which is what pre-1.x modules did, and it renders a ¥1,000 product as ¥100,000. A decimal or a float is rejected outright — money is never inferred. - One product is one object, however many variations it has. Send variations nested in
variants, never as separate top-level items. They fold into the parent: SKUs become searchable, attributes become facets, and the price becomes a range. Sending them separately also multiplies what the merchant is charged against their plan. visiblefails closed. Anything not explicitlytrueis unreachable through the public search key. This is the most common cause of "my products are not appearing".versionis your clock, and last write wins. An item whose version is not greater than the indexed one is skipped as stale. Milliseconds since epoch is the convention. A constant or absent version means out-of-order delivery silently overwrites newer data.- A bad item is skipped, not fatal. One unmappable item is recorded with a reason and the rest of the batch still applies. You will not get a 4xx telling you which one — check the merchant's sync health panel.
What this contract does NOT cover
Stated explicitly, because a contract's silences are where integrations break:
- Tax. There is one price field. Whether it includes tax is the merchant's own store setting; NitroSearch indexes and displays exactly what you send and performs no tax calculation of any kind.
- Multi-currency and multi-storefront. One store sends one currency. A storefront serving several currencies is not supported yet.
- Authentication, transport and rate limits. Request signing and endpoint behaviour are documented with the integration guide, not here. This repository describes the payload.
- The search API. This is the ingest direction only.