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

> ## Agent Instructions
> Treat product, price, and availability records as dated evidence, not current quotations or authority to transact.
> Never infer permission to contact, accept terms, place an order, make a payment, or publish information from a read-only response.

# Supplier record contract

> Prepare source-derived product, capacity and service records for the integration preview.

Contract version: **0.1.0**. [Release status](/suppliers/status) · [JSON schema](https://middleman.mintlify.app/downloads/supplier-records.schema.json) · [Preview OpenAPI](https://middleman.mintlify.app/downloads/supplier-openapi.json).

## Validation envelope

`POST /api/v1/supplier/validate` accepts a strict JSON object with `schemaVersion`, `source` and `records`. Unknown fields are rejected, including caller-supplied company IDs or approval flags. The API key determines the company.

`source` contains a stable `id`, a `system` name and `mode` (`api` or `sdk`). `records` contains one to 50 records. The full request must fit in 256 KiB. Required nullable fields must be present as `null` when unknown.

## Record fields

| Field                                    | Type / rule                                                  |
| ---------------------------------------- | ------------------------------------------------------------ |
| `sourceRecordId`                         | Stable source identifier; unique within a batch              |
| `sourceVersion`                          | Source revision/change token or deterministic record digest  |
| `kind`                                   | `product`, `capacity` or `service`                           |
| `title`                                  | Source-derived description, up to 500 characters             |
| `manufacturer`, `manufacturerPartNumber` | Strings or `null`                                            |
| `unit`                                   | Source unit, up to 40 characters                             |
| `condition`                              | `new`, `used`, `refurbished` or `unknown`                    |
| `availability`                           | Quantity, window, location and lead time, as described below |
| `pricing`                                | Public-price context and quantity tiers, or `null`           |
| `sourceUpdatedAt`                        | ISO 8601 timestamp with zone, or `null`                      |
| `observedAt`, `expiresAt`                | ISO 8601 timestamps with zone                                |
| `status`                                 | `active` or `withdrawn`                                      |

Identifiers start with an alphanumeric character and may contain letters, numbers, `.`, `_`, `:`, `/` and `-`, up to 160 characters. An MPN is not automatically the same as a supplier listing ID.

### Availability

* `quantity`: unsigned decimal string or `null`.
* `window`: `{ "start": "…", "end": "…" }` or `null`; required for `capacity`, with end after start.
* `location`: string or `null`.
* `leadTimeDays`: whole number from 0 to 3650, or `null`.

### Pricing

When a price is known, provide `currency` (three uppercase letters), `country` (two uppercase letters), `audience: "public"`, `taxBasis` (`net`, `gross` or `unknown`), `taxRate` (decimal proportion or `null`), positive `minimumOrderQuantity`, positive `orderMultiple` and one to 50 `tiers`.

Each tier has a positive `minimumQuantity` and nonnegative `unitPrice`. Decimal strings support up to 12 integer digits and eight fractional digits. Tier thresholds must be unique and ascending. A zero price is allowed only when the source actually says zero. Currency/country syntax validation is not proof that a market context is valid.

### Freshness

Expiry must follow observation by at most 24 hours. An observation more than 60 seconds in the future is rejected. Expired observations are rejected. A known source modification time cannot follow observation. Never freshen cached source data by replacing its timestamps.

The JSON schema covers structural constraints. Cross-field rules, freshness and tier ordering are also enforced by the server.

## Successful validation

```json theme={"system"}
{
  "valid": true,
  "schemaVersion": "0.1.0",
  "recordsValidated": 1,
  "persisted": false,
  "admitted": false
}
```

No data is saved to a catalogue and no source URL is fetched. Validation cannot prove source access, source truth, continuous synchronization or permission to share. A synthetic example passing validation is not an integrated supplier.

## Supplier-hosted interface: proposed

For a later pull integration, we propose that your service expose a provider manifest, cursor-paginated catalogue, read-only availability checks and health endpoint. These paths would be on **your** service, not the Middleman API:

| Proposed path                 | Purpose                                                   |
| ----------------------------- | --------------------------------------------------------- |
| `GET /v1/provider`            | Schema version, capabilities, supported markets and units |
| `GET /v1/catalog?cursor=…`    | Stable identities and source-derived records              |
| `POST /v1/availability/check` | Read current price/stock/capacity for identified records  |
| `GET /v1/health`              | Source connection and last successful refresh             |

This transport and its authentication/admission process are not yet released. Do not deploy an unauthenticated endpoint or send us credentials on the assumption that it will be polled. Prepare the record mapping first; confirm transport details before production work.
