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: 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