shelfatlas-com Observed Prices API

The ObservedPrices API from shelfatlas-com — 1 operation(s) for observedprices.

Operations 1

GET /api/v1/public/catalog/observed-prices Latest observed shelf prices inside your coverage packages (SA-0158) #

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/shelfatlas-com:shelfatlas-com-observedprices-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

shelfatlas-com-observedprices-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: ShelfAtlas Catalog Observed Prices API
  version: 1.0.0
  description: 'Read access to normalised Danish retail catalog data — products, offers, stores, and chains. Authenticate with a Bearer `sa_live_` API key. This document is the contract the official ShelfAtlas SDKs conform to. Data coverage: the offer feed covers every major Danish chain, but the curated product catalog is smaller and actively expanding — an empty data array from /products/{id}/offers or /price-history means no offers are linked to that product yet, not an error.'
  termsOfService: https://shelfatlas.com/legal/terms
servers:
- url: https://api.shelfatlas.com
  description: Production
security:
- bearerAuth: []
tags:
- name: ObservedPrices
paths:
  /api/v1/public/catalog/observed-prices:
    get:
      operationId: listObservedPrices
      summary: Latest observed shelf prices inside your coverage packages (SA-0158)
      description: 'The B2B read behind Shelf Intelligence: the latest APPROVED shelf observation per product per store, limited to the coverage packages this API key has been granted (a package = a customer''s stores × products, kept observed by the field team). A key without an active package gets 403 `no_coverage_package`. Only human observations — never catalog prices — and no reporter identity: `trust` is the source class (`partner`, `established`, `new`). Private, never cached.'
      tags:
      - ObservedPrices
      parameters:
      - name: ean
        in: query
        required: false
        schema:
          type: string
          pattern: ^\d{8}$|^\d{13}$
        description: Only this product (EAN-8/13).
      - name: store_id
        in: query
        required: false
        schema:
          type: string
          format: uuid
        description: Only this store.
      - name: since
        in: query
        required: false
        schema:
          type: string
          format: date-time
        description: Only observations at or after this instant.
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 500
          default: 200
        description: Page size (1–500, default 200).
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          minimum: 0
          default: 0
        description: Rows to skip.
      responses:
        '200':
          description: Latest observed price per (product, store) the key may see.
          content:
            application/json:
              schema:
                type: object
                required:
                - ok
                - data
                - limit
                - offset
                additionalProperties: false
                properties:
                  ok:
                    type: boolean
                    enum:
                    - true
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ObservedPrice'
                  limit:
                    type: integer
                  offset:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: The key has no active coverage package (`no_coverage_package`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  responses:
    RateLimited:
      description: Rate limit or monthly limit reached (`rate_limited` / `monthly_limit_reached`).
      headers:
        Retry-After:
          description: Seconds to wait before retrying (present on `rate_limited`).
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    BadRequest:
      description: Invalid parameters (`invalid_params`, `incompatible_params`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ServiceUnavailable:
      description: Temporary backend failure (`service_unavailable`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Missing, invalid, or revoked API key (`missing_api_key` / `invalid_api_key` / `revoked_api_key`).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    Error:
      type: object
      additionalProperties: true
      required:
      - error
      properties:
        error:
          type: string
          description: Machine-readable error code.
        message:
          type: string
        detail:
          type: string
        retry_after_sec:
          type: integer
          description: Seconds to wait before retrying (429).
        plan:
          type: string
          description: Caller's resolved plan id (present on monthly_limit_reached).
        limit:
          type: integer
          description: The plan monthly request quota (present on monthly_limit_reached).
        used:
          type: integer
          description: Requests already spent this UTC month (present on monthly_limit_reached).
        resets_at:
          type: string
          format: date-time
          description: When the quota resets — next UTC month start (present on monthly_limit_reached).
        next_plan:
          type: object
          nullable: true
          description: The cheapest plan with a larger quota, or null at the top of the ladder.
          properties:
            id:
              type: string
            name:
              type: string
            monthly_price_dkk:
              type: integer
            monthly_request_quota:
              type: integer
        plans_url:
          type: string
          format: uri
          description: Public pricing page — no sign-in required.
        upgrade_url:
          type: string
          format: uri
    ObservedPrice:
      type: object
      additionalProperties: false
      required:
      - ean
      - label
      - store
      - priceCents
      - stockStatus
      - observedAt
      - trust
      properties:
        ean:
          type: string
          description: EAN-8/13 as the package lists it.
        label:
          type: string
          description: The package's human label for the product.
        store:
          type: object
          additionalProperties: false
          required:
          - id
          - name
          - chainSlug
          - chainName
          - lat
          - lng
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
            chainSlug:
              type: string
            chainName:
              type: string
            lat:
              type: number
            lng:
              type: number
        priceCents:
          type: integer
          nullable: true
          description: Shelf price in øre (DKK×100); null for a stock-only observation.
        stockStatus:
          type: string
          enum:
          - in_stock
          - low_stock
          - out_of_stock
        observedAt:
          type: string
          format: date-time
          description: When the shelf was seen.
        trust:
          type: string
          enum:
          - partner
          - established
          - new
          description: Source class — a partner surface, a contributor with 5+ approved observations, or a newer contributor.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'A ShelfAtlas API key: `Authorization: Bearer sa_live_<key>`.'
    deviceTokenAuth:
      type: apiKey
      in: header
      name: X-Device-Token
      description: 'Anonymous per-device identity for POST /api/v1/observations: a UUID the client generates and keeps locally. Any UUID version is accepted — the check is purely the 8-4-4-4-12 hex-digit shape.'