SNHP Offer API

General offer-graph engine: compile / profile / quote a JSON menu spec (discount-only, never above list)

Operations 3

POST /v1/offer/compile Compile a JSON menu spec into an offer graph (summary) #
POST /v1/offer/profile Profile a menu: FREE vs LEVER per dimension (the divergence profiler) #
POST /v1/offer/quote Quote a buyer on a menu — Nash split, discount-only (never above list) #

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/snhp-dev-offer-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

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

snhp-dev-offer-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Game Theory Layer for AI Agents Offer API
  description: 'Start with ONE tool: POST /v1/negotiate/turn — plain-dollar price negotiation (your walk-away + the other side''s offers in dollars -> the counter to send, a ready-to-send message, accept/walk advice).'
  version: 0.1.0
tags:
- name: Offer
  description: 'General offer-graph engine: compile / profile / quote a JSON menu spec (discount-only, never above list)'
paths:
  /v1/offer/compile:
    post:
      tags:
      - Offer
      summary: Compile a JSON menu spec into an offer graph (summary)
      description: 'Body: the declarative menu spec itself (dims of kind choice / addon / preference / fulfillment / quantity, each with typed options, an optional deps graph, and a cost stack of const / salvage_on_expiry / scarcity_shadow / batch_economies). Returns the compiled graph summary — dims, options, cost stack, and how many dependency-valid configurations the engine will search. Free, stateless, nothing is stored. Malformed or oversized specs get a 422 with a plain-English reason.'
      operationId: offer_compile_v1_offer_compile_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MenuSpec'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/offer/profile:
    post:
      tags:
      - Offer
      summary: 'Profile a menu: FREE vs LEVER per dimension (the divergence profiler)'
      description: 'The signature endpoint. Give it {spec, state?} and every dimension is classified by probing the cost model: FREE (zero cost gradient — a costless customization the buyer just gets their favorite of, never a price lever) or LEVER (changing the option moves the shop''s effective cost — a real negotiation surface). Each verdict carries the probed dollar spread and a one-line why. Verdicts are properties of the menu''s economics, not of any buyer.'
      operationId: offer_profile_v1_offer_profile_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfileRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/offer/quote:
    post:
      tags:
      - Offer
      summary: Quote a buyer on a menu — Nash split, discount-only (never above list)
      description: 'Give it {spec, state?, buyer, config?, opts?} and get the Quote receipt: price, listv, save, feasible, why. The engine searches every valid configuration (or prices the pinned `config`), anchors the disagreement on the buyer''s best full-price menu order, and picks the Nash split of the created surplus. HARD GUARANTEE: discount-only — the price is never above the menu''s list value (`never_above_list: true`, enforced in code). Quotes are advisory engine output on a caller-supplied menu, not a binding offer (`advisory: true`). The response also carries an `attestation`: a signed, replayable NotaryReceipt proving the quote was discount-only and stamping the report-independence regime (b) — verify it offline with GET /v1/notary/key (d=false: v1 has no outside-option attestation).'
      operationId: offer_quote_v1_offer_quote_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuoteRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    ProfileRequest:
      properties:
        spec:
          $ref: '#/components/schemas/MenuSpec'
        state:
          anyOf:
          - $ref: '#/components/schemas/StateSpec'
          - type: 'null'
      additionalProperties: false
      type: object
      required:
      - spec
      title: ProfileRequest
    BuyerSpec:
      properties:
        values:
          additionalProperties:
            additionalProperties:
              type: number
            type: object
          type: object
          title: Values
          description: dim_id -> option_id -> per-unit dollar value
        qty_decay:
          type: number
          maximum: 1.0
          minimum: 0.0
          title: Qty Decay
          description: each extra unit is worth this fraction of the previous
          default: 0.15
        outside:
          type: number
          maximum: 1000000000.0
          minimum: 0.0
          title: Outside
          description: the buyer's outside-option surplus in dollars
          default: 0.0
        balk:
          type: number
          maximum: 1.0
          minimum: 0.0
          title: Balk
          description: probability a walk-in is turned away by the queue
          default: 0.0
        defer:
          additionalProperties:
            type: number
          type: object
          title: Defer
          description: slot_ticks -> dollar cost of waiting for that slot
      additionalProperties: false
      type: object
      title: BuyerSpec
      description: 'A separable buyer (core/engine.SeparableBuyer): per-option dollar

        values, a quantity-decay ladder, and scalar outside/balk/defer reports.'
    DepsSpec:
      properties:
        valid_on:
          additionalProperties:
            items:
              type: string
            type: array
          type: object
          title: Valid On
        requires:
          additionalProperties:
            items:
              type: string
            type: array
          type: object
          title: Requires
        excludes:
          additionalProperties:
            items:
              type: string
            type: array
          type: object
          title: Excludes
      additionalProperties: false
      type: object
      title: DepsSpec
    QuoteRequest:
      properties:
        spec:
          $ref: '#/components/schemas/MenuSpec'
        state:
          anyOf:
          - $ref: '#/components/schemas/StateSpec'
          - type: 'null'
        buyer:
          $ref: '#/components/schemas/BuyerSpec'
        config:
          anyOf:
          - additionalProperties: true
            type: object
          - type: 'null'
          title: Config
          description: 'pin dims: dim_id -> option id | [option ids] (addon) | int (quantity). Omit to search every valid cart.'
        opts:
          $ref: '#/components/schemas/QuoteOptsSpec'
      additionalProperties: false
      type: object
      required:
      - spec
      - buyer
      title: QuoteRequest
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    QuoteOptsSpec:
      properties:
        quote_lookers:
          type: boolean
          title: Quote Lookers
          description: False = refuse buyers who'd never pay list (IC floor)
          default: true
        min_price_frac:
          type: number
          maximum: 1.0
          minimum: 0.0
          title: Min Price Frac
          description: never quote below this fraction of list
          default: 0.0
        qty_appetite:
          type: boolean
          title: Qty Appetite
          description: don't upsell a unit the buyer values below its cost
          default: false
        seller_weight:
          type: number
          maximum: 1.0
          minimum: 0.0
          title: Seller Weight
          description: 0.5 = symmetric Nash; →1 tilts surplus to the seller
          default: 0.5
      additionalProperties: false
      type: object
      title: QuoteOptsSpec
      description: The hosted subset of core/engine.QuoteOpts.
    MenuSpec:
      properties:
        name:
          type: string
          maxLength: 120
          title: Name
          default: ''
        dims:
          items:
            $ref: '#/components/schemas/DimSpec'
          type: array
          maxItems: 8
          minItems: 1
          title: Dims
        deps:
          $ref: '#/components/schemas/DepsSpec'
        cost:
          items:
            anyOf:
            - type: string
            - additionalProperties: true
              type: object
          type: array
          maxItems: 8
          title: Cost
      additionalProperties: false
      type: object
      required:
      - dims
      title: MenuSpec
      description: 'core.api.build_graph''s declarative spec, validated for hosting.


        DUAL-ACCEPT: a body carrying `items` is the FRIENDLY pasted menu (what

        arena/web/yourmenu.js accepts) and is compiled to the raw `dims` spec via

        menu_spec.friendly_to_dims before the hosting checks below run — so the

        hosted engine takes the exact JSON an agent reads off that page. A body

        carrying `dims` is the native spec and passes through untouched.'
    DimSpec:
      properties:
        id:
          type: string
          maxLength: 64
          minLength: 1
          title: Id
        kind:
          type: string
          title: Kind
        options:
          items:
            $ref: '#/components/schemas/OptionSpec'
          type: array
          maxItems: 12
          title: Options
        qty_cap:
          type: integer
          maximum: 12.0
          minimum: 1.0
          title: Qty Cap
          default: 1
        negotiable:
          anyOf:
          - type: string
            enum:
            - free
            - lever
            - auto
          - type: 'null'
          title: Negotiable
      additionalProperties: false
      type: object
      required:
      - id
      - kind
      title: DimSpec
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    OptionSpec:
      properties:
        id:
          type: string
          maxLength: 64
          minLength: 1
          title: Id
        label:
          type: string
          maxLength: 120
          title: Label
          default: ''
        price_delta:
          type: number
          maximum: 1000000000.0
          minimum: 0.0
          title: Price Delta
          description: This option's contribution to the cart's LIST price
          default: 0.0
        unit_cost:
          type: number
          maximum: 1000000000.0
          minimum: 0.0
          title: Unit Cost
          default: 0.0
        salvage:
          type: number
          maximum: 1000000000.0
          minimum: 0.0
          title: Salvage
          default: 0.0
        perishable:
          type: boolean
          title: Perishable
          default: false
        stock_limited:
          type: boolean
          title: Stock Limited
          default: false
        immediate:
          type: boolean
          title: Immediate
          default: true
        slot_ticks:
          type: integer
          maximum: 10000.0
          minimum: 0.0
          title: Slot Ticks
          default: 0
      additionalProperties: false
      type: object
      required:
      - id
      title: OptionSpec
    StateSpec:
      properties:
        tick:
          type: integer
          minimum: 0.0
          title: Tick
          default: 0
        inventory:
          additionalProperties:
            type: number
          type: object
          title: Inventory
          description: option_id -> units on hand (finite stock)
        capacity:
          additionalProperties:
            type: number
          type: object
          title: Capacity
          description: slot_ticks -> units a deferred slot can still absorb
        expiring:
          items:
            type: string
          type: array
          maxItems: 128
          title: Expiring
          description: option ids currently priced at salvage (batch expiring)
        expected_demand:
          additionalProperties:
            type: number
          type: object
          title: Expected Demand
          description: option_id -> expected rest-of-horizon list-price demand
      additionalProperties: false
      type: object
      title: StateSpec
      description: 'The shop moment the cost model reads (core/state.ShopState). All

        fields optional — an omitted state is a neutral shop (no inventory

        signals, nothing expiring, unconstrained capacity).'