# OpenStock integration recipes

Response examples are illustrative unless labelled as a synthetic fixture. They preserve the API envelope but do not represent current availability, measured performance or checkout verification. Example codes cannot be redeemed; example links omit live attribution. Use the URLs returned by your real request.

Set OPENSTOCK_API_KEY in your environment. Keep API credentials on your backend. Replace illustrative idempotency keys with keys scoped to your shopper and offer session.

API reference: https://api.openstock.sh/docs
OpenAPI: https://api.openstock.sh/openapi.json
JSON examples: https://openstock.sh/recipes.json

## Generate a merchant-backed code

A direct merchant integration can create a single-use code when you request it. The source field makes that capability visible in the response. A generated code still has merchant eligibility rules; preserve the offer description and conditions when presenting it.

Run live: https://openstock.sh/demo?recipe=generated
Open the demo and select Run recipe for a real Brooklinen search and offer request. The response inspector shows the exact requests and returned data.

### What to inspect

- source: generated identifies a code created through the merchant integration. Inspect this field on each offer.

- single_use: A single-use code can be redeemed once. Repeating the same idempotent request does not create a second redemption.

- conditions + description: Keep minimum spend, product, customer and subscription restrictions visible. An empty conditions array does not prove a cart is eligible.

- cashback + activation_url: Cashback is separate from the code. Use the actual returned link and applicable offer terms.

### Resolve the exact merchant domain

Domain matching resolves a known merchant without choosing among similar names. Pass the returned id into the next request.

```bash
curl -sS -X POST 'https://api.openstock.sh/v1/merchants/search' \
  -H "Authorization: Bearer $OPENSTOCK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"queries":[{"query_id":"brooklinen","type":"domain","value":"brooklinen.com"}]}'
```

Request JSON:
```json
{
  "queries": [
    {
      "query_id": "brooklinen",
      "type": "domain",
      "value": "brooklinen.com"
    }
  ]
}
```

Illustrative full response:
```json
{
  "results": [
    {
      "query_id": "brooklinen",
      "items": [
        {
          "id": "01g4s5d0h956te86ff90h6xts4",
          "name": "Brooklinen",
          "domains": [
            "brooklinen.com",
            "brooklinen2.myshopify.com",
            "shop.app/checkout/9517126"
          ],
          "popularity_rank": 1710,
          "estimated_shipping": {
            "unit": "days",
            "median": 3,
            "q1": 2,
            "q3": 4,
            "basis": "measured_delivery",
            "sample_size": null
          }
        }
      ]
    }
  ]
}
```

### Request an offer with the merchant ID

Use the resolved merchant ID. Replace the example idempotency key with a stable, opaque key for this shopper and offer session. Keep it for retries. Terms, cashback and availability in a live response can differ from this illustration.

```bash
curl -sS -X POST 'https://api.openstock.sh/v1/merchants/codes' \
  -H "Authorization: Bearer $OPENSTOCK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"queries":[{"query_id":"brooklinen","merchant_id":"01g4s5d0h956te86ff90h6xts4","idempotency_key":"replace-with-your-shopper-session-key","limit":1}]}'
```

Request JSON:
```json
{
  "queries": [
    {
      "query_id": "brooklinen",
      "merchant_id": "01g4s5d0h956te86ff90h6xts4",
      "idempotency_key": "replace-with-your-shopper-session-key",
      "limit": 1
    }
  ]
}
```

Illustrative full response:
```json
{
  "results": [
    {
      "query_id": "brooklinen",
      "cashback": {
        "value_type": "percent",
        "value_amount": 3
      },
      "partnered": true,
      "activation_url": "https://api.openstock.sh/mr/01g4s5d0h956te86ff90h6xts4",
      "suppressed_code_count": 0,
      "items": [
        {
          "code": "EXAMPLE-NOT-REDEEMABLE",
          "source": "generated",
          "probability": 1,
          "single_use": true,
          "value_type": "percent",
          "value_amount": 15,
          "currency": null,
          "conditions": [],
          "redirect_url": "https://api.openstock.sh/mr/01g4s5d0h956te86ff90h6xts4?code=EXAMPLE-NOT-REDEEMABLE",
          "expires_at": null,
          "last_success": null,
          "description": "15% off",
          "apply_count": null,
          "success_count": null
        }
      ]
    }
  ]
}
```

## Compare generated and public codes

Resolve merchant identity once, then batch offer queries. Source describes where each offer came from; probability describes its reported reliability. A partnership flag is merchant context, so read the source of each item rather than treating every offer at a partnered merchant as generated.

Run live: https://openstock.sh/demo?recipe=compare
Open the demo and select Run recipe to compare Brooklinen and Nike using current responses. The demo shows the returned probability for public codes, including low-confidence results; the inspector keeps the full evidence visible.

### What to inspect

- source: generated is created through an integration; merchant_issued is a configured merchant offer; observed is a public code.

- probability: Use the returned score for observed codes. The 0.01 below is an illustrative low-confidence case, not a prediction for your next request.

- apply_count + success_count: Available checkout evidence can be null. The probability uses weighted recent evidence and need not equal the all-time success ratio.

- query_id: Correlate each result with your request; the two merchants remain distinct throughout the batch.

### Request both sources in one batch

These are known merchant IDs; resolve domains with merchant search in a new integration. No min_probability is set so a low-confidence public code can be inspected. Live results may be empty or have different values.

```bash
curl -sS -X POST 'https://api.openstock.sh/v1/merchants/codes' \
  -H "Authorization: Bearer $OPENSTOCK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"queries":[{"query_id":"brooklinen","merchant_id":"01g4s5d0h956te86ff90h6xts4","idempotency_key":"replace-with-your-shopper-session-key","limit":1},{"query_id":"nike","merchant_id":"01g4s4gvb1kdc8kz69cm5q2b4f","idempotency_key":"replace-with-your-nike-session-key","limit":1}]}'
```

Request JSON:
```json
{
  "queries": [
    {
      "query_id": "brooklinen",
      "merchant_id": "01g4s5d0h956te86ff90h6xts4",
      "idempotency_key": "replace-with-your-shopper-session-key",
      "limit": 1
    },
    {
      "query_id": "nike",
      "merchant_id": "01g4s4gvb1kdc8kz69cm5q2b4f",
      "idempotency_key": "replace-with-your-nike-session-key",
      "limit": 1
    }
  ]
}
```

Illustrative full response:
```json
{
  "results": [
    {
      "query_id": "brooklinen",
      "cashback": {
        "value_type": "percent",
        "value_amount": 3
      },
      "partnered": true,
      "activation_url": "https://api.openstock.sh/mr/01g4s5d0h956te86ff90h6xts4",
      "suppressed_code_count": 0,
      "items": [
        {
          "code": "EXAMPLE-NOT-REDEEMABLE",
          "source": "generated",
          "probability": 1,
          "single_use": true,
          "value_type": "percent",
          "value_amount": 15,
          "currency": null,
          "conditions": [],
          "redirect_url": "https://api.openstock.sh/mr/01g4s5d0h956te86ff90h6xts4?code=EXAMPLE-NOT-REDEEMABLE",
          "expires_at": null,
          "last_success": null,
          "description": "15% off",
          "apply_count": null,
          "success_count": null
        }
      ]
    },
    {
      "query_id": "nike",
      "cashback": {
        "value_type": "percent",
        "value_amount": 3
      },
      "partnered": false,
      "activation_url": "https://api.openstock.sh/mr/01g4s4gvb1kdc8kz69cm5q2b4f",
      "suppressed_code_count": 0,
      "items": [
        {
          "code": "EXAMPLE-PUBLIC-CODE",
          "source": "observed",
          "probability": 0.01,
          "single_use": false,
          "value_type": "percent",
          "value_amount": 10,
          "currency": null,
          "conditions": [],
          "redirect_url": "https://api.openstock.sh/mr/01g4s4gvb1kdc8kz69cm5q2b4f?code=EXAMPLE-PUBLIC-CODE",
          "expires_at": null,
          "last_success": null,
          "description": "10% off",
          "apply_count": 12,
          "success_count": 0
        }
      ]
    }
  ]
}
```

## Explain a delivery estimate

Shipping comes from merchant search. Its basis tells an assistant how to qualify the answer. A median is a typical observed or estimated time, not a delivery promise for a particular address or order.

Run live: https://openstock.sh/demo?recipe=shipping
Open the demo and select Run recipe to inspect current delivery responses for Everlane and AG1. Read the returned basis; data coverage and values can change.

### What to inspect

- basis: measured_delivery: Observed order-to-delivery data for this merchant. Present the median with the interquartile range when available.

- basis: network_default: A general network estimate when merchant delivery data is unavailable. Label it as a network estimate.

- basis: processing_plus_transit_estimate: Merchant processing data plus assumed transit time. This is an estimate rather than observed end-to-end delivery.

- sample_size: Null means the sample count is unavailable; it does not mean zero orders. Null estimated_shipping means no applicable estimate.

### Read shipping provenance in the search response

These illustrative results show both measured delivery and a default. The catalogue can resolve a merchant even when merchant-specific delivery evidence is unavailable.

```bash
curl -sS -X POST 'https://api.openstock.sh/v1/merchants/search' \
  -H "Authorization: Bearer $OPENSTOCK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"queries":[{"query_id":"everlane","type":"domain","value":"everlane.com"},{"query_id":"ag1","type":"domain","value":"drinkag1.com"}]}'
```

Request JSON:
```json
{
  "queries": [
    {
      "query_id": "everlane",
      "type": "domain",
      "value": "everlane.com"
    },
    {
      "query_id": "ag1",
      "type": "domain",
      "value": "drinkag1.com"
    }
  ]
}
```

Illustrative full response:
```json
{
  "results": [
    {
      "query_id": "everlane",
      "items": [
        {
          "id": "01g4s5dc138qsnh4egsjys8g9c",
          "name": "Everlane",
          "domains": [
            "everlane.com",
            "m34kzg-ke.myshopify.com",
            "shop.app/checkout/62379163734"
          ],
          "popularity_rank": 966,
          "estimated_shipping": {
            "unit": "days",
            "median": 6,
            "q1": 4,
            "q3": 8,
            "basis": "measured_delivery",
            "sample_size": null
          }
        }
      ]
    },
    {
      "query_id": "ag1",
      "items": [
        {
          "id": "01hybscj8sjsxdejx39apgsbv9",
          "name": "AG1",
          "domains": [
            "drinkag1.com"
          ],
          "popularity_rank": null,
          "estimated_shipping": {
            "unit": "days",
            "median": 4,
            "q1": 3,
            "q3": 5,
            "basis": "network_default",
            "sample_size": null
          }
        }
      ]
    }
  ]
}
```

## Distinguish purchases from visits

This fixture demonstrates the response shape and assistant presentation. It is synthetic, contains no real shopper data, and does not demonstrate live network coverage. Live history returns available interactions for a shopper you are authorized to look up; hashing an email identifies that shopper but does not grant authorization.

Open fixture demo: https://openstock.sh/demo?recipe=history
Select Run recipe in the demo to combine the synthetic history fixture with current merchant and offer responses. The demo labels the two data sources separately.

### What to inspect

- type: purchased: A purchase interaction. Do not infer a product, date, amount or order count: this endpoint returns merchant-level interaction types.

- type: visited: A browsing interaction; never describe it as a purchase.

- email_sha256: SHA-256 of the lowercase, trimmed email. This fixture uses a reserved example identity and is not seeded into live lookup.

- items: []: No returned history. Treat the absence as unavailable context, rather than evidence that the shopper has never bought anything.

### Fetch the synthetic response fixture

This public fixture requires no API key. It contains two purchase interactions and one visit, and is the same fixture used by the demo.

```bash
curl -fsS 'https://openstock.sh/examples/shopper-history.json'
```



Synthetic fixture response:
```json
{
  "results": [
    {
      "query_id": "example-shopper",
      "items": [
        {
          "merchant_id": "01g4s5d0h956te86ff90h6xts4",
          "merchant_name": "Brooklinen",
          "type": "purchased"
        },
        {
          "merchant_id": "01g4s5dc138qsnh4egsjys8g9c",
          "merchant_name": "Everlane",
          "type": "purchased"
        },
        {
          "merchant_id": "01g4s4gvb1kdc8kz69cm5q2b4f",
          "merchant_name": "NIKE",
          "type": "visited"
        }
      ]
    }
  ]
}
```

### Understand the live request contract

The example hash is not a seeded live shopper. An unknown shopper returns an empty items array, as illustrated here. For an authorized real lookup, substitute the correctly normalized email hash; do not send the raw address.

```bash
curl -sS -X POST 'https://api.openstock.sh/v1/shoppers/history' \
  -H "Authorization: Bearer $OPENSTOCK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"queries":[{"query_id":"example-shopper","email_sha256":"3a32f737ca25fb3d367dd3c8aaa91e9bf73f31445b0377a8de073eb33276dcb8"}]}'
```

Request JSON:
```json
{
  "queries": [
    {
      "query_id": "example-shopper",
      "email_sha256": "3a32f737ca25fb3d367dd3c8aaa91e9bf73f31445b0377a8de073eb33276dcb8"
    }
  ]
}
```

Illustrative full response:
```json
{
  "results": [
    {
      "query_id": "example-shopper",
      "items": []
    }
  ]
}
```

## Handle absence without guessing

An assistant needs a useful answer when nothing clears its quality bar. Merchant resolution and code availability are separate outcomes. An empty code list may still include an activation link and a cashback offer; inspect those fields separately.

Run live: https://openstock.sh/demo?recipe=miss
Open the demo and select Run recipe to search a deliberately nonexistent .invalid domain. The demo presents the miss directly, without inventing a merchant or discount.

### What to inspect

- search items[0].id: null: The merchant did not resolve. Ask for a better name or domain instead of making a codes request with a guessed ID.

- codes items: []: No code was returned; it does not by itself establish that the merchant is unknown.

- suppressed_code_count: A positive count means the probability threshold or result limit removed candidates.

- activation_url + cashback: A known merchant can still have an activation link. Cashback is available only when its own field is non-null.

### Resolve an unknown domain

A well-formed search can succeed with no matching merchant. Preserve the null result as normal application data.

```bash
curl -sS -X POST 'https://api.openstock.sh/v1/merchants/search' \
  -H "Authorization: Bearer $OPENSTOCK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"queries":[{"query_id":"unknown","type":"domain","value":"openstock-no-such-store.invalid"}]}'
```

Request JSON:
```json
{
  "queries": [
    {
      "query_id": "unknown",
      "type": "domain",
      "value": "openstock-no-such-store.invalid"
    }
  ]
}
```

Illustrative full response:
```json
{
  "results": [
    {
      "query_id": "unknown",
      "items": [
        {
          "id": null,
          "name": null,
          "domains": [],
          "popularity_rank": null,
          "estimated_shipping": null
        }
      ]
    }
  ]
}
```

### Filter public codes by your quality bar

This illustration shows a known merchant whose codes do not clear 0.5. The live response can contain qualifying codes when evidence changes. Do not promise that this request will return either a code or an empty list.

```bash
curl -sS -X POST 'https://api.openstock.sh/v1/merchants/codes' \
  -H "Authorization: Bearer $OPENSTOCK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"queries":[{"query_id":"nike","merchant_id":"01g4s4gvb1kdc8kz69cm5q2b4f","idempotency_key":"replace-with-your-filter-session-key","min_probability":0.5,"limit":3}]}'
```

Request JSON:
```json
{
  "queries": [
    {
      "query_id": "nike",
      "merchant_id": "01g4s4gvb1kdc8kz69cm5q2b4f",
      "idempotency_key": "replace-with-your-filter-session-key",
      "min_probability": 0.5,
      "limit": 3
    }
  ]
}
```

Illustrative full response:
```json
{
  "results": [
    {
      "query_id": "nike",
      "cashback": {
        "value_type": "percent",
        "value_amount": 3
      },
      "partnered": false,
      "activation_url": "https://api.openstock.sh/mr/01g4s4gvb1kdc8kz69cm5q2b4f",
      "suppressed_code_count": 3,
      "items": []
    }
  ]
}
```

## Replay without issuing another code

A tool call may be retried after a timeout or by an assistant continuing a session. Keep a stable idempotency key for that offer request so a successful retry reuses the generated code. Compare the returned code; do not assume every response field is a frozen snapshot.

Run live: https://openstock.sh/demo?recipe=replay
Select Run recipe for Brooklinen once, then Run again in the demo. It reuses the daily idempotency key within the same UTC day; compare the request keys and generated codes in both runs. After midnight UTC, the demo uses a new key.

### What to inspect

- idempotency_key: Use the same opaque key for the same shopper and offer session. Replace the documentation placeholder; do not share it across real shoppers.

- code: The replay should return the same generated code while the underlying offer is available. A new key represents a new issuance request. The public demo changes its key at midnight UTC.

- single_use: Replaying a single-use code does not reset its redemption state or make it reusable at checkout.

- conditions + expires_at: Continue to respect the returned terms and expiry. A null expiry does not prove the code lasts forever.

### Request an offer with the merchant ID

Use the resolved merchant ID. Replace the example idempotency key with a stable, opaque key for this shopper and offer session. Keep it for retries. Terms, cashback and availability in a live response can differ from this illustration.

```bash
curl -sS -X POST 'https://api.openstock.sh/v1/merchants/codes' \
  -H "Authorization: Bearer $OPENSTOCK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"queries":[{"query_id":"brooklinen","merchant_id":"01g4s5d0h956te86ff90h6xts4","idempotency_key":"replace-with-your-shopper-session-key","limit":1}]}'
```

Request JSON:
```json
{
  "queries": [
    {
      "query_id": "brooklinen",
      "merchant_id": "01g4s5d0h956te86ff90h6xts4",
      "idempotency_key": "replace-with-your-shopper-session-key",
      "limit": 1
    }
  ]
}
```

Illustrative full response:
```json
{
  "results": [
    {
      "query_id": "brooklinen",
      "cashback": {
        "value_type": "percent",
        "value_amount": 3
      },
      "partnered": true,
      "activation_url": "https://api.openstock.sh/mr/01g4s5d0h956te86ff90h6xts4",
      "suppressed_code_count": 0,
      "items": [
        {
          "code": "EXAMPLE-NOT-REDEEMABLE",
          "source": "generated",
          "probability": 1,
          "single_use": true,
          "value_type": "percent",
          "value_amount": 15,
          "currency": null,
          "conditions": [],
          "redirect_url": "https://api.openstock.sh/mr/01g4s5d0h956te86ff90h6xts4?code=EXAMPLE-NOT-REDEEMABLE",
          "expires_at": null,
          "last_success": null,
          "description": "15% off",
          "apply_count": null,
          "success_count": null
        }
      ]
    }
  ]
}
```

### Repeat the exact request

Send the same body, including merchant_id and idempotency_key. The repeated illustrative response contains the same code. The demo keeps the original request available in the inspector. Its Run again button reuses the same key within a UTC day; compare both request keys before assessing the generated code.

```bash
curl -sS -X POST 'https://api.openstock.sh/v1/merchants/codes' \
  -H "Authorization: Bearer $OPENSTOCK_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"queries":[{"query_id":"brooklinen","merchant_id":"01g4s5d0h956te86ff90h6xts4","idempotency_key":"replace-with-your-shopper-session-key","limit":1}]}'
```

Request JSON:
```json
{
  "queries": [
    {
      "query_id": "brooklinen",
      "merchant_id": "01g4s5d0h956te86ff90h6xts4",
      "idempotency_key": "replace-with-your-shopper-session-key",
      "limit": 1
    }
  ]
}
```

Illustrative full response:
```json
{
  "results": [
    {
      "query_id": "brooklinen",
      "cashback": {
        "value_type": "percent",
        "value_amount": 3
      },
      "partnered": true,
      "activation_url": "https://api.openstock.sh/mr/01g4s5d0h956te86ff90h6xts4",
      "suppressed_code_count": 0,
      "items": [
        {
          "code": "EXAMPLE-NOT-REDEEMABLE",
          "source": "generated",
          "probability": 1,
          "single_use": true,
          "value_type": "percent",
          "value_amount": 15,
          "currency": null,
          "conditions": [],
          "redirect_url": "https://api.openstock.sh/mr/01g4s5d0h956te86ff90h6xts4?code=EXAMPLE-NOT-REDEEMABLE",
          "expires_at": null,
          "last_success": null,
          "description": "15% off",
          "apply_count": null,
          "success_count": null
        }
      ]
    }
  ]
}
```