JENNi Runs API

Open, inspect and close runs. Every write belongs to a run, and a run is how JENNi attributes what you sent and (in snapshot mode) what to remove. ### How every ingestion integration is shaped Write your catalog and inventory into the JENNi product graph, then reconcile what JENNi holds against what you sent. ## The shape of every integration Work is always scoped to a **run**. A run is the unit of source attribution, batch idempotency and — in snapshot mode — the full-replace window. 1. `POST /provider/v1/stores` — register each store once. (Bringing a new business onto JENNi? Register it as a **retailer** first — see the Retailers guide — and pass its `retailer_id` here.) 2. `POST /provider/v1/runs` — open a run. 3. Push batches against that run (`/inventory/levels/bulk`, `/products/bulk`, or `/inventory/snapshots`). 4. `POST /provider/v1/runs/{run_id}/close` — close it. 5. `GET /provider/v1/products` / `GET /provider/v1/inventory/levels` — read back what landed. Only an **open** run accepts writes; a batch against a closed, expired or failed run is rejected with `409`. ## Two ingestion modes - **Mode A — incremental** (`mode: "incremental"`, scope `provider.write`). Each batch is a delta. Send what changed. Nothing is removed implicitly. - **Mode B — snapshot** (`mode: "snapshot"`, scope `provider.ingest`). The run carries the COMPLETE set of levels for ONE store. Anything absent from the snapshot is soft-deleted when the run closes. A snapshot run must declare its `store_id` and `expected_items` when it is opened. ## Partial success is normal Both bulk endpoints return a per-item envelope. **`200` means every item was accepted; `207` means at least one was not.** Always walk `results[]` and join on `event_id` — a 2xx status alone does not mean every item landed. An item is `accepted` (durable), `rejected` (permanently bad — do not retry unchanged) or `deferred` (indeterminate upstream failure — retry it). ## Errors Every 4xx and 5xx is RFC-7807 `application/problem+json`. Branch on the stable `type` URI, never on `title` or `detail`. Every response carries `X-Request-Id`; quote it in support requests. ## Tenancy Your tenant and your provider are derived from your API key. There is no tenant parameter anywhere in this API — not in a path, not in a query string, not in a body. A key is scoped to exactly one provider.

GitHub OpenAPI

Operations 5

GET /provider/v1/runs List your runs #
POST /provider/v1/runs Open a run #
GET /provider/v1/runs/{run_id} Get a run #
POST /provider/v1/runs/{run_id}/close Close a run #
GET /provider/v1/runs/{run_id}/items List the items recorded against a run #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/jennipro-com:jennipro-com-runs-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

jennipro-com-runs-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  contact:
    email: partners@jennipro.com
    name: JENNi partner integrations
  description: 'One API, read by four kinds of partner. **Get started** (left) is the same for everyone:

    sign up, get a key, make five calls. Then pick who you are: each card names the guide to

    read first and the API sections you will actually call, in that order. The sidebar is

    grouped the same way; everything cross-cutting (errors, paging, limits, versioning) sits

    under **Reference** at the end.


    POS systems


    You run the point of sale, inventory or product-data system for retailers, and you push their catalog and live stock into JENNi.


    What you do: register each store, open a run, push products and stock levels (or a full snapshot), close the run, read back what landed.


    Read, then call: POS: catalog & inventory → Stores · Runs · Catalog · Inventory


    First call: POST /provider/v1/stores


    Live in production.


    Brands


    You own the product content — titles, images, descriptions, GTINs — for products that retailers stock, and you want JENNi''s listings to carry your version.


    What you do: send product records through the same ingestion lane a POS uses, then make sure each one clears the readiness bar, because a record that lands but is not ready is never sold.


    Read, then call: Brands → Product readiness → Catalog (listed under POS systems)


    First call: GET /provider/v1/products


    Same lane as POS. Brand-to-retailer matching is handled by JENNi, not by an API call.


    Marketplaces & channels


    You are a demand channel — a marketplace, delivery app or storefront — that lists JENNi merchants'' stock and sends orders back.


    What you do: read one store''s shelf at a time, poll or receive changes, and agree an order path with JENNi (orders in are a JENNi-built adapter, not a public endpoint).


    Read, then call: Marketplace & channel → Channel · Events · Webhooks


    First call: GET /channel/v1/stores


    The read contract is settled and documented; it is enabled per channel — the guide says what is callable today.


    Fulfillment & delivery


    You pick, pack, ship or hand over orders for JENNi merchants.


    What you do: today, plan. The fulfillment service has no partner-callable route; the guide documents what is built so you can scope against it.


    Read: Fulfillment & delivery


    First call: none yet — talk to your JENNi contact.


    Planning only today; talk to your JENNi contact before building.


    ## Before your first call


    - **Get a credential:** *Sign in / Sign up* (top right) → verify your email → *Request a

    key*. JENNi approves it and you claim the secret once — Quickstart walks

    through it.

    - **Base URLs:** `https://prod.jennipro.net` is production; `https://dev.jennipro.app` is the

    sandbox, with its own credentials issued on request.

    - **Credential:** `X-Jenni-Api-Key: .` on every request — see

    Authentication and Scopes. Your tenant and provider come

    from the key; no tenant id ever travels in a path or body.

    - **Errors** are RFC-7807 `application/problem+json`; branch on `type`, quote

    `X-Request-Id` to support — see Errors.

    - **Writes** carry `Idempotency-Key`; lists page with `cursor` + `limit` — see

    Idempotency and Pagination.


    Where a capability is not yet available to partners, the page says so in place.'
  title: JENNi Catalog & Inventory Ingestion Runs API
  version: '2026-09-20'
servers:
- description: Production
  url: https://prod.jennipro.net
- description: Development / integration sandbox
  url: https://dev.jennipro.app
security:
- PartnerApiKey: []
tags:


# --- truncated at 32 KB (65 KB total) ---
# Full source: https://artifacts.apis.io/jennipro-com/openapi/jennipro-com-runs-api-openapi.yml