Blumee Search API

Find offers by meaning or by photo. Budgeted.

Operations 2

POST /v1/search/text Search by meaning #
POST /v1/search/photo Search by photo #

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-search-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-search-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Blumee Search 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: Search
  description: Find offers by meaning or by photo. Budgeted.
paths:
  /v1/search/text:
    post:
      tags:
      - Search
      operationId: searchText
      summary: Search by meaning
      description: 'Free-text search. The server extracts filters from the query with an LLM, embeds the

        normalised query and ranks by vector similarity, so it answers a description

        ("something elegant but not stiff for my boss''s 60th birthday, under 50 EUR")

        rather than a keyword list.

        For a keyword list, `/v1/catalog` is faster, free and exact.


        **Costs money** (one LLM extraction, cached, plus one embedding), so it is also under a daily budget: 200 calls per day from one address, 5000 across everyone, resetting at 00:00 UTC. Over it you get 429 `budget_exhausted`.


        The extracted `filters` come back with the hits: show them or use them, because a query

        the extractor read differently than you meant is the usual reason a result looks wrong.'
      parameters:
      - 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
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TextSearchRequest'
            example:
              query: etwas Elegantes zum 60. Geburtstag meiner Chefin, bis 50 Euro
              lang: de
              limit: 12
      responses:
        '200':
          description: Ranked offers plus the filters the server read out of the query.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TextSearchResponse'
        '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/search/photo:
    post:
      tags:
      - Search
      operationId: searchPhoto
      summary: Search by photo
      description: 'Upload a photo of a bouquet or a plant; get the species identified and offers that match.


        **Costs money** (a Pl@ntNet identification and an OpenAI Vision call), so it is also under a daily budget: 40 calls per day from one address, 800 across everyone, resetting at 00:00 UTC. Over it you get 429 `budget_exhausted`. The Pl@ntNet

        quota is a hard external ceiling shared with the mobile app, so this endpoint can refuse

        while the rest of the API is fine.


        **Ask before you call it.** It costs a paid identification per call and uploads someone

        else''s photograph. If you can already see the picture yourself, you do not need this:

        describe the arrangement to `/v1/search/text` instead — same catalog, no cost, faster.


        `identify.matches[].confidence` are scores, not probabilities: 0.4 on the top match of a

        mixed bouquet is normal. An empty `hits` with `intent: "houseplant"` is not a failure — the

        catalog is mostly cut flowers.'
      parameters:
      - name: Accept-Language
        in: header
        description: Language of the identification labels. `de` or `en`; anything else is treated as `en`.
        schema:
          type: string
      - 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
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
              - images
              properties:
                images:
                  type: array
                  minItems: 1
                  maxItems: 3
                  description: One to three photos of the same arrangement, 10 MB each, `image/jpeg`, `image/png`, `image/webp` or `image/heic`. One good photo beats three mediocre ones.
                  items:
                    type: string
                    format: binary
                mask_b64:
                  type: string
                  description: Optional base64 PNG foreground mask. When present, colours are sampled from the masked pixels only.
      responses:
        '200':
          description: What the photo shows, and the offers that match it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PhotoSearchResponse'
        '400':
          description: Request failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: An image exceeded 10 MB.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: Unsupported image type.
          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:
    TextSearchResponse:
      type: object
      properties:
        hits:
          type: array
          items:
            $ref: '#/components/schemas/SearchHit'
        total:
          type: integer
          minimum: 0
        filters:
          $ref: '#/components/schemas/ExtractedFilters'
        timings:
          type: object
          properties:
            extract:
              type: number
              minimum: 0
            embed:
              type: number
              minimum: 0
            search:
              type: number
              minimum: 0
            total:
              type: number
              minimum: 0
          required:
          - extract
          - embed
          - search
          - total
          additionalProperties: false
        cache:
          type: object
          properties:
            extract:
              type: boolean
          required:
          - extract
          additionalProperties: false
      required:
      - hits
      - total
      - filters
      - timings
      - cache
      additionalProperties: false
    PhotoSearchHit:
      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
        source:
          type: string
          enum:
          - catalog
          - search
        similarity:
          type: number
          minimum: 0
          maximum: 1
      required:
      - id
      - title
      - price
      - currency
      - imageUrl
      - partner
      - flowers
      - colors
      - occasion
      - available
      - source
      additionalProperties: false
    IdentifyResponse:
      type: object
      properties:
        ok:
          type: boolean
          const: true
        language:
          type: string
        verdict:
          type: string
          enum:
          - flower
          - low_confidence
          - no_known_genera
          - not_a_bouquet
        organConfidence:
          anyOf:
          - type: number
            minimum: 0
            maximum: 1
          - type: 'null'
        matches:
          type: array
          items:
            $ref: '#/components/schemas/IdentifyMatch'
        generaRollup:
          type: array
          items:
            type: object
            properties:
              genus:
                type: string
              confidence:
                type: number
                minimum: 0
                maximum: 1
              knownSpecies:
                type: boolean
              label:
                type: string
            required:
            - genus
            - confidence
            - knownSpecies
            additionalProperties: false
        palette:
          type: array
          items:
            type: string
        style:
          type: string
        occasionGuess:
          type: string
        arrangement:
          type: object
          properties:
            shape:
              type: string
            symmetry:
              type: string
            stemCountEstimate:
              type: integer
              minimum: 0
            wrapping:
              type: string
          required:
          - shape
          - symmetry
          - stemCountEstimate
          - wrapping
          additionalProperties: false
        freshness:
          type: string
        providersUsed:
          type: array
          items:
            type: string
            enum:
            - plantnet
            - openai-vision
        raw:
          type: object
          properties:
            plantnet:
              anyOf:
              - type: object
                properties:
                  language:
                    type: string
                  bestMatch:
                    type:
                    - string
                    - 'null'
                  predictedOrgans:
                    type: array
                    items:
                      type: object
                      properties:
                        organ:
                          type: string
                        score:
                          type: number
                      required:
                      - organ
                      - score
                      additionalProperties: false
                  remainingRequests:
                    type: number
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        scientificName:
                          type: string
                        scientificNameWithoutAuthor:
                          type: string
                        genus:
                          type:
                          - string
                          - 'null'
                        family:
                          type:
                          - string
                          - 'null'
                        commonNames:
                          type: array
                          items:
                            type: string
                        score:
                          type: number
                        gbifId:
                          type: string
                        powoId:
                          type: string
                        iucnCategory:
                          type: string
                      required:
                      - scientificName
                      - scientificNameWithoutAuthor
                      - genus
                      - family
                      - commonNames
                      - score
                      additionalProperties: false
                required:
                - language
                - bestMatch
                - predictedOrgans
                - remainingRequests
                - results
                additionalProperties: false
              - type: 'null'
            vision:
              anyOf:
              - type: object
                properties:
                  model:
                    type: string
                  isBouquet:
                    type: boolean
                  isPottedPlant:
                    type: boolean
                  flowers:
                    type: array
                    items:
                      type: object
                      properties:
                        commonName:
                          type: string
                        scientificGuess:
                          type: string
                        approximateCount:
                          type: integer
                          minimum: 0
                        colors:
                          type: array
                          items:
                            type: string
                        confidence:
                          type: number
                          minimum: 0
                          maximum: 1
                      required:
                      - commonName
                      - scientificGuess
                      - approximateCount
                      - colors
                      - confidence
                      additionalProperties: false
                  colors:
                    type: array
                    items:
                      type: string
                  style:
                    type: string
                  occasionGuess:
                    type: string
                  overallConfidence:
                    type: number
                    minimum: 0
                    maximum: 1
                  arrangement:
                    type: object
                    properties:
                      shape:
                        type: string
                      symmetry:
                        type: string
                      stemCountEstimate:
                        type: integer
                        minimum: 0
                      wrapping:
                        type: string
                    required:
                    - shape
                    - symmetry
                    - stemCountEstimate
                    - wrapping
                    additionalProperties: false
                  freshness:
                    type: string
                  usage:
                    type: object
                    properties:
                      promptTokens:
                        type: integer
                        minimum: 0
                      completionTokens:
                        type: integer
                        minimum: 0
                      totalTokens:
                        type: integer
                        minimum: 0
                    required:
                    - promptTokens
                    - completionTokens
                    - totalTokens
                    additionalProperties: false
                required:
                - model
                - isBouquet
                - flowers
                - colors
                - style
                - occasionGuess
                - overallConfidence
                - arrangement
                - freshness
                additionalProperties: false
              - type: 'null'
          required:
          - plantnet
          - vision
          additionalProperties: false
        timings:
          type: object
          additionalProperties:
            type: integer
            minimum: 0
          propertyNames:
            enum:
            - plantnet
            - openai-vision
      required:
      - ok
      - language
      - verdict
      - organConfidence
      - matches
      - generaRollup
      - providersUsed
      - raw
      - timings
      additionalProperties: false
    ExtractedColor:
      type: object
      properties:
        hex:
          type: string
          pattern: ^#[0-9a-fA-F]{6}$
        share:
          type: number
          minimum: 0
          maximum: 1
        name:
          type: string
      required:
      - hex
      - share
      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.
    SearchHit:
      type: object
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        description:
          type:
          - string
          - 'null'
        price:
          type: string
        currency:
          type: string
        imageUrl:
          type:
          - string
          - 'null'
        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:
          type: object
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
          required:
          - id
          - name
          additionalProperties: false
        flowers:
          type: array
          items:
            type: string
        colors:
          type: array
          items:
            type: string
        occasion:
          type:
          - string
          - 'null'
        affiliateUrl:
          type: string
        similarity:
          type: number
      required:
      - id
      - title
      - description
      - price
      - currency
      - imageUrl
      - imageUrls
      - partner
      - flowers
      - colors
      - occasion
      - affiliateUrl
      - similarity
      additionalProperties: false
    IdentifyMatch:
      type: object
      properties:
        kind:
          type: string
          enum:
          - species
          - genus
          - label
        scientificName:
          type: string
        genus:
          type: string
        family:
          type: string
        label:
          type: string
        confidence:
          type: number
          minimum: 0
          maximum: 1
        knownSpecies:
          type: boolean
        speciesId:
          type: string
          format: uuid
        gbifId:
          type: string
        providers:
          type: array
          items:
            type: string
            enum:
            - plantnet
            - openai-vision
          minItems: 1
        approximateCount:
          type: integer
          minimum: 0
        colors:
          type: array
          items:
            type: string
        aliasesDe:
          type: array
          items:
            type: string
      required:
      - kind
      - scientificName
      - confidence
      - knownSpecies
      - providers
      additionalProperties: false
    PhotoSearchResponse:
      type: object
      properties:
        identify:
          $ref: '#/components/schemas/IdentifyResponse'
        intent:
          type: string
          enum:
          - bouquet
          - houseplant
          - unknown
          default: unknown
        hits:
          type: array
          items:
            $ref: '#/components/schemas/PhotoSearchHit'
        total:
          type: integer
          minimum: 0
        breakdown:
          type: object
          properties:
            catalog:
              type: integer
              minimum: 0
            search:
              type: integer
              minimum: 0
            merged:
              type: integer
              minimum: 0
          required:
          - catalog
          - search
          - merged
          additionalProperties: false
        extractedColors:
          type: array
          items:
            $ref: '#/components/schemas/ExtractedColor'
          default: []
        timings:
          type: object
          properties:
            identify:
              type: integer
              minimum: 0
            catalog:
              type: integer
              minimum: 0
            search:
              type: integer
              minimum: 0
            colors:
              type: integer
              minimum: 0
              default: 0
            total:
              type: integer
              minimum: 0
          required:
          - identify
          - catalog
          - search
          - total
          additionalProperties: false
      required:
      - identify
      - hits
      - total
      - breakdown
      - timings
      additionalProperties: false
    CatalogPartner:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
      required:
      - id
      - name
      additionalProperties: false
    TextSearchRequest:
      type: object
      properties:
        query:
          type: string
          minLength: 1
          maxLength: 500
        lang:
          type: string
          enum:
          - en
          - de
        filters:
          type: object
          properties:
            flowers:
              type: array
              items:
                type: string
            colors:
              type: array
              items:
                type: string
            occasion:
              type: string
            size:
              type: string
              enum:
              - small
              - medium
              - large
            style:
              type: string
            priceMaxEur:
              type: number
              exclusiveMinimum: 0
            priceMinEur:
              type: number
              minimum: 0
            deliveryMaxDays:
              type: integer
              exclusiveMinimum: 0
          additionalProperties: false
        limit:
          type: integer
          minimum: 1
          maximum: 50
          default: 20
      required:
      - query
      - lang
      additionalProperties: false
    ExtractedFilters:
      type: object
      properties:
        flowers:
          type: array
          items:
            type: string
          default: []
        colors:
          type: array
          items:
            type: string
          default: []
        occasion:
          type:
          - string
          - 'null'
          default: null
        style:
          type:
          - string
          - 'null'
          default: null
        size:
          anyOf:
          - type: string
            enum:
            - small
            - medium
            - large
          - type: 'null'
          default: null
        priceMinEur:
          type:
          - number
          - 'null'
          default: null
        priceMaxEur:
          type:
          - number
          - 'null'
          default: null
        deliveryMaxDays:
          anyOf:
          - type: integer
            exclusiveMinimum: 0
          - type: 'null'
          default: null
        normalisedQuery:
          type: string
      required:
      - normalisedQuery
      additionalProperties: false
externalDocs:
  description: How to use Blumee as an agent, in prose.
  url: https://blumee.app/agent/api.md