Blumee Catalog API

Browse and filter the offers.

Operations 4

GET /v1/catalog Filter the catalog #
GET /v1/catalog/facets Available filter values with counts #
GET /v1/catalog/stats Compact catalog snapshot #
GET /v1/products/{id} One offer in full #

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/blumee-app:blumee-app-catalog-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

blumee-app-catalog-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Blumee Catalog API
  version: 0.1.0
  summary: Flower-delivery offers from German partner florists, searchable by text and photo.
  description: 'Blumee compares bouquets and potted plants that vetted German florists deliver. This API is

    the read side of that catalog: filter it, search it by meaning, or identify the flowers in a

    photo and get offers that look like it.


    ### Three things worth knowing before the endpoint list


    **No authentication, and none is coming.** There are no accounts, no keys, no sign-up. Send

    requests. What protects the service is spend: 60 requests per minute per caller, plus a

    daily budget on the endpoints that call a paid model. See `https://blumee.app/auth.md`.


    **Blumee sells nothing.** Every order is placed with the named partner shop, and Blumee earns

    an affiliate commission on referred purchases. Nothing here can place an order, and no

    endpoint changes state.


    **Send buyers through `https://blumee.app/go/{productId}?src=agent`.** That is the link to hand

    a person — it records the click, attributes it, and forwards to the partner. Do not fetch it

    yourself: a click no human made is worthless to them and corrupts the data on both sides.

    The `affiliateUrl` some responses carry is the partner deep link behind it; using it directly

    works but drops the attribution that pays for this catalog. And say the link is an ad — in

    Germany that disclosure is a legal requirement, not a courtesy.


    ### Cheaper than this API


    If you want the whole catalog rather than an answer to a question, fetch the static export at

    `https://blumee.app/agent/offers.json`. It is a CDN file, needs no budget, and is regenerated

    on every catalog rebuild. Pages of the site also carry in-browser WebMCP tools, and there are

    agent skills at `https://blumee.app/.well-known/agent-skills/index.json`.


    ### Not described here


    The app-internal endpoints (conversational chat, raw identification, telemetry, the build-time

    dump, Prometheus metrics) are deliberately left out — they exist, they are not for general use,

    and the shapes they return change with the app.'
  contact:
    name: Blumee
    email: info@blumee.app
    url: https://blumee.app/de/impressum/
  termsOfService: https://blumee.app/de/agb/
  license:
    name: Blumee terms of use
    url: https://blumee.app/de/agb/
servers:
- url: https://api.blumee.app
  description: Production
security: []
tags:
- name: Catalog
  description: Browse and filter the offers.
paths:
  /v1/catalog:
    get:
      tags:
      - Catalog
      operationId: listCatalog
      summary: Filter the catalog
      description: 'Structured, cursor-paged listing. Filters are ANDed; the values inside one

        comma-separated filter are ORed.


        `total` is the number of products matching the filters, not a relevance count — a large

        total with `sort=relevance` still means only the first handful are good matches.


        Free (no daily budget), but still rate-limited. For the whole catalog at once, use

        `https://blumee.app/agent/offers.json` instead of paging through this.'
      parameters:
      - name: lang
        in: query
        description: Language of the returned labels. The catalog itself is German.
        schema:
          type: string
          enum:
          - en
          - de
          default: de
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 50
          default: 20
      - name: cursor
        in: query
        description: Opaque `nextCursor` from the previous page. Do not construct one.
        schema:
          type: string
          maxLength: 512
      - name: sort
        in: query
        description: '`relevance` ranks by how well a product matches the `flowers`/`colors` filters and is only meaningful together with them.'
        schema:
          type: string
          enum:
          - default
          - relevance
          - price_asc
          - price_desc
          - newest
          default: default
      - name: flowers
        in: query
        description: Comma-separated flower names, German or English (`Rose,Tulpe`). Matched against a synonym table, so `Pfingstrose` and `peony` find the same products.
        style: form
        explode: false
        schema:
          type: array
          maxItems: 50
          items:
            type: string
            maxLength: 64
      - name: colors
        in: query
        description: Comma-separated colours, German (`rosa,weiß`).
        style: form
        explode: false
        schema:
          type: array
          maxItems: 50
          items:
            type: string
            maxLength: 32
      - name: occasions
        in: query
        description: Comma-separated occasions, matched exactly. Use `occasionKeywords` to match loosely.
        style: form
        explode: false
        schema:
          type: array
          maxItems: 50
          items:
            type: string
            maxLength: 64
      - name: occasionKeywords
        in: query
        description: Comma-separated substrings, case-insensitive, OR-joined. Partner feeds carry compound occasion strings ("Geburtstag / Frühsommer / Hochzeit"), so a substring match finds what an exact one misses.
        style: form
        explode: false
        schema:
          type: array
          maxItems: 50
          items:
            type: string
            maxLength: 64
      - name: partnerIds
        in: query
        description: Comma-separated partner UUIDs, as returned in `items[].partner.id`.
        style: form
        explode: false
        schema:
          type: array
          maxItems: 50
          items:
            type: string
            format: uuid
      - name: priceMinEur
        in: query
        schema:
          type: number
          minimum: 0
      - name: priceMaxEur
        in: query
        schema:
          type: number
          exclusiveMinimum: 0
      - name: deliveryMaxDays
        in: query
        description: Keeps products whose *slowest* advertised delivery is within N days. This is the filter for a deadline that must not be missed; it excludes a lot.
        schema:
          type: integer
          minimum: 1
          maximum: 60
      - name: available
        in: query
        description: Defaults to true. Setting it false includes products the partner feed has stopped listing; they cannot be ordered.
        schema:
          type: boolean
          default: true
      - name: X-Device-Id
        in: header
        required: false
        description: 'Optional caller-chosen UUID. It groups a session''s calls so the funnel from search to click can be joined, and it is what ends up as the affiliate `clickref` on a click you hand over. It is not authentication and grants nothing: rate limits are charged to your IP either way.'
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: A page of offers.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CatalogResponse'
        '400':
          description: Request failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit (`rate_limited`) or daily budget (`budget_exhausted`) exhausted. Both are per-connection first, so a retry from the same address will not help before `Retry-After`.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
            X-RateLimit-Limit:
              description: Requests allowed in the current 60-second window.
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unhandled error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/catalog/facets:
    get:
      tags:
      - Catalog
      operationId: getCatalogFacets
      summary: Available filter values with counts
      description: Every occasion, partner, flower and colour currently present, with how many products carry it, plus the price range and delivery buckets. Use it to pick filter values that will actually return something.
      responses:
        '200':
          description: Facet counts over the available catalog.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CatalogFacets'
        '400':
          description: Request failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit (`rate_limited`) or daily budget (`budget_exhausted`) exhausted. Both are per-connection first, so a retry from the same address will not help before `Retry-After`.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
            X-RateLimit-Limit:
              description: Requests allowed in the current 60-second window.
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unhandled error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/catalog/stats:
    get:
      tags:
      - Catalog
      operationId: getCatalogStats
      summary: Compact catalog snapshot
      description: The same picture as `/v1/catalog/facets` with the identifiers stripped and price buckets added — small enough to put in a prompt.
      responses:
        '200':
          description: Counts over the available catalog.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CatalogStats'
        '400':
          description: Request failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit (`rate_limited`) or daily budget (`budget_exhausted`) exhausted. Both are per-connection first, so a retry from the same address will not help before `Retry-After`.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
            X-RateLimit-Limit:
              description: Requests allowed in the current 60-second window.
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unhandled error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /v1/products/{id}:
    get:
      tags:
      - Catalog
      operationId: getProduct
      summary: One offer in full
      description: 'Description, every image, delivery window, shipping cost and the identified species.


        A product that the partner feed has stopped listing still resolves here with

        `available: false`. It cannot be ordered, and `/go/{id}` will refuse it.'
      parameters:
      - name: id
        in: path
        required: true
        description: Product UUID.
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The offer.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductDetail'
        '400':
          description: Request failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No such product.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit (`rate_limited`) or daily budget (`budget_exhausted`) exhausted. Both are per-connection first, so a retry from the same address will not help before `Retry-After`.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
            X-RateLimit-Limit:
              description: Requests allowed in the current 60-second window.
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: Requests left in the current window.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unhandled error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    ProductDetail:
      type: object
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        description:
          type:
          - string
          - 'null'
        price:
          type: string
        currency:
          type: string
        imageUrls:
          type: array
          items:
            type: string
        images:
          type: array
          items:
            type: object
            properties:
              src:
                type: string
              width:
                anyOf:
                - type: integer
                  exclusiveMinimum: 0
                - type: 'null'
              height:
                anyOf:
                - type: integer
                  exclusiveMinimum: 0
                - type: 'null'
              variants:
                type: array
                items:
                  type: object
                  properties:
                    url:
                      type: string
                    width:
                      type: integer
                      exclusiveMinimum: 0
                  required:
                  - url
                  - width
                  additionalProperties: false
            required:
            - src
            - width
            - height
            - variants
            additionalProperties: false
          default: []
        partner:
          $ref: '#/components/schemas/CatalogPartner'
        flowers:
          type: array
          items:
            type: string
        colors:
          type: array
          items:
            type: string
        occasion:
          type:
          - string
          - 'null'
        size:
          type:
          - string
          - 'null'
        style:
          type:
          - string
          - 'null'
        category:
          type:
          - string
          - 'null'
        categoryPath:
          type: array
          items:
            type: string
          default: []
        available:
          type: boolean
        affiliateUrl:
          type: string
        deliveryDaysMin:
          anyOf:
          - type: integer
          - type: 'null'
        deliveryDaysMax:
          anyOf:
          - type: integer
          - type: 'null'
        deliveryCostCents:
          anyOf:
          - type: integer
          - type: 'null'
        species:
          type: array
          items:
            $ref: '#/components/schemas/ProductFlowerLink'
        createdAt:
          type: string
        updatedAt:
          type: string
      required:
      - id
      - title
      - description
      - price
      - currency
      - imageUrls
      - partner
      - flowers
      - colors
      - occasion
      - size
      - style
      - category
      - available
      - affiliateUrl
      - deliveryDaysMin
      - deliveryDaysMax
      - deliveryCostCents
      - species
      - createdAt
      - updatedAt
      additionalProperties: false
    CatalogStats:
      type: object
      properties:
        totalAvailable:
          type: integer
          minimum: 0
        partners:
          type: array
          items:
            $ref: '#/components/schemas/StatEntry'
        occasions:
          type: array
          items:
            $ref: '#/components/schemas/StatEntry'
        flowers:
          type: array
          items:
            $ref: '#/components/schemas/StatEntry'
        colors:
          type: array
          items:
            $ref: '#/components/schemas/StatEntry'
        priceRange:
          type: object
          properties:
            minEur:
              type: number
            maxEur:
              type: number
          required:
          - minEur
          - maxEur
          additionalProperties: false
        priceBuckets:
          type: array
          items:
            $ref: '#/components/schemas/PriceBucket'
        deliveryBuckets:
          type: array
          items:
            $ref: '#/components/schemas/DeliveryBucket'
      required:
      - totalAvailable
      - partners
      - occasions
      - flowers
      - colors
      - priceRange
      - priceBuckets
      - deliveryBuckets
      additionalProperties: false
    StatEntry:
      type: object
      properties:
        value:
          type: string
        count:
          type: integer
          minimum: 0
      required:
      - value
      - count
      additionalProperties: false
    CatalogFacets:
      type: object
      properties:
        occasions:
          type: array
          items:
            $ref: '#/components/schemas/FacetEntry'
        partners:
          type: array
          items:
            $ref: '#/components/schemas/FacetEntry'
        flowers:
          type: array
          items:
            $ref: '#/components/schemas/FacetEntry'
        colors:
          type: array
          items:
            $ref: '#/components/schemas/FacetEntry'
        priceRange:
          type: object
          properties:
            minEur:
              type: number
            maxEur:
              type: number
          required:
          - minEur
          - maxEur
          additionalProperties: false
        deliveryBuckets:
          type: array
          items:
            $ref: '#/components/schemas/DeliveryBucket'
      required:
      - occasions
      - partners
      - flowers
      - colors
      - priceRange
      - deliveryBuckets
      additionalProperties: false
    Error:
      type: object
      description: Every non-2xx response has this shape. `code` is stable and safe to branch on; `message` is prose and may change.
      required:
      - error
      properties:
        error:
          type: object
          required:
          - code
          - message
          properties:
            code:
              type: string
              enum:
              - validation_error
              - bad_request
              - not_found
              - payload_too_large
              - unsupported_media_type
              - rate_limited
              - budget_exhausted
              - service_unavailable
              - internal
            message:
              type: string
            details:
              description: Present on validation errors and budget refusals.
    CatalogItem:
      type: object
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        price:
          type: string
        currency:
          type: string
        imageUrl:
          type:
          - string
          - 'null'
        image:
          anyOf:
          - type: object
            properties:
              src:
                type: string
              width:
                anyOf:
                - type: integer
                  exclusiveMinimum: 0
                - type: 'null'
              height:
                anyOf:
                - type: integer
                  exclusiveMinimum: 0
                - type: 'null'
              variants:
                type: array
                items:
                  type: object
                  properties:
                    url:
                      type: string
                    width:
                      type: integer
                      exclusiveMinimum: 0
                  required:
                  - url
                  - width
                  additionalProperties: false
            required:
            - src
            - width
            - height
            - variants
            additionalProperties: false
          - type: 'null'
          default: null
        partner:
          $ref: '#/components/schemas/CatalogPartner'
        flowers:
          type: array
          items:
            type: string
        colors:
          type: array
          items:
            type: string
        occasion:
          type:
          - string
          - 'null'
        available:
          type: boolean
      required:
      - id
      - title
      - price
      - currency
      - imageUrl
      - partner
      - flowers
      - colors
      - occasion
      - available
      additionalProperties: false
    CatalogPartner:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
      required:
      - id
      - name
      additionalProperties: false
    FacetEntry:
      type: object
      properties:
        value:
          type: string
        label:
          type: string
        count:
          type: integer
          minimum: 0
      required:
      - value
      - label
      - count
      additionalProperties: false
    PriceBucket:
      type: object
      properties:
        maxEur:
          type: number
          exclusiveMinimum: 0
        count:
          type: integer
          minimum: 0
      required:
      - maxEur
      - count
      additionalProperties: false
    ProductFlowerLink:
      type: object
      properties:
        speciesId:
          type: string
          format: uuid
        scientificName:
          type: string
        genus:
          type:
          - string
          - 'null'
        commonNames:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
        confidence:
          type: number
      required:
      - speciesId
      - scientificName
      - genus
      - commonNames
      - confidence
      additionalProperties: false
    DeliveryBucket:
      type: object
      properties:
        daysMax:
          type: integer
          exclusiveMinimum: 0
        count:
          type: integer
          minimum: 0
      required:
      - daysMax
      - count
      additionalProperties: false
    CatalogResponse:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/CatalogItem'
        nextCursor:
          type:
          - string
          - 'null'
        total:
          type: integer
          minimum: 0
      required:
      - items
      - nextCursor
      - total
      additionalProperties: false
externalDocs:
  description: How to use Blumee as an agent, in prose.
  url: https://blumee.app/agent/api.md