Documentation index for this site: /llms.txt

Designer and niche perfume from 3 mlDecanted from the original bottles30-day returns

Developers

parfum1 has a free, read-only perfume API and MCP server. An agent or an app can search the catalogue, read a perfume with its notes and every decant size, price and stock as the product page shows them, browse the perfume houses and read the delivery, returns, payment and contact facts. No key and no account are needed.

Connect an MCP client

The MCP server runs at https://parfum1.com/mcp. It is stateless: every request is a JSON-RPC message sent with POST, and every answer is plain JSON, so there is no session to keep. It is read-only and needs no key.

SettingValue
Endpointhttps://parfum1.com/mcp
TransportStreamable HTTP, POST with JSON responses (a GET answers 405)
AuthenticationNone
Protocol versions2025-11-25, 2025-06-18, 2025-03-26
Methodsinitialize, notifications/initialized, ping, tools/list, tools/call
Server cardhttps://parfum1.com/.well-known/mcp/server-card.json
Server version1.0.0

Clients that take a server address only need the endpoint. A client configured with a JSON file usually reads like this:

{
  "mcpServers": {
    "parfum1": {
      "url": "https://parfum1.com/mcp"
    }
  }
}

Check the connection and call a tool straight from a terminal:

curl -s https://parfum1.com/mcp \
  -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"example","version":"1.0.0"}}}'

curl -s https://parfum1.com/mcp \
  -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_perfumes","arguments":{"query":"hacivat","per_page":1}}}'

MCP tools

The server offers 5 tools. All of them are read-only (they carry the readOnlyHint annotation) and each has a JSON Schema for its input. An input mistake or an unknown handle comes back as a tool result marked as an error, with a message that says what to change.

ToolWhat it doesInputs
search_perfumesSearch the parfum1 catalogue by words in the perfume name, house or scent family (all words must match, accents ignored), optionally within one house. Returns a page of perfumes in popularity order with the starting price, stock, rating and product URL.query, house, page, per_page
get_perfumeRead one perfume by its handle: name, house, description, top, heart and base notes, and every size (3, 10 and 30 ml) with the price, the struck regular price, price per ml and whether it is in stock, exactly as the product page shows them, plus the full bottle (listed out of stock) and the product URL.handle (required)
list_housesList the perfume houses in the catalogue, A to Z, with their handle, whether the house is a niche house, the number of perfumes and the house page URL. Optionally filter by words in the house name.query
get_houseRead one perfume house by its handle: its introduction, the number of perfumes and the first 50 of them with starting price and stock. Use search_perfumes with the house for the rest.handle (required)
get_store_infoRead how parfum1 works, with the same facts as its help pages: delivery (dispatch, cost, countries), returns, payment methods, contact details and its own social profiles. Pass a topic for one, or none for all four.topic

REST API

The same 5 operations are plain GET requests under https://parfum1.com/api/perfume/v1. Every answer is JSON. The OpenAPI 3.1 description, with schemas and examples, is at https://parfum1.com/openapi.json.

OperationRequestParameters
searchPerfumesGET https://parfum1.com/api/perfume/v1/perfumesquery, house, page, per_page
getPerfumeGET https://parfum1.com/api/perfume/v1/perfumes/{handle}handle (required)
listHousesGET https://parfum1.com/api/perfume/v1/housesquery
getHouseGET https://parfum1.com/api/perfume/v1/houses/{handle}handle (required)
getStoreInfoGET https://parfum1.com/api/perfume/v1/store-infotopic

Search for a perfume:

curl -s 'https://parfum1.com/api/perfume/v1/perfumes?query=hacivat&per_page=1'

The answer (page 1 of 2; values change with the catalogue):

{
  "query": "hacivat",
  "house": null,
  "page": 1,
  "per_page": 1,
  "total": 2,
  "total_pages": 2,
  "results": [
    {
      "handle": "hacivat-by-nishane",
      "name": "Nishane Hacivat",
      "house": "Nishane",
      "family": "woody",
      "gender": "men",
      "from_price_eur": 12.15,
      "from_size_ml": 3,
      "was_price_eur": 18.9,
      "in_stock": true,
      "rating": 4.9,
      "review_count": 47,
      "url": "https://parfum1.com/perfume/hacivat-by-nishane",
      "api_url": "https://parfum1.com/api/perfume/v1/perfumes/hacivat-by-nishane",
      "image": "https://img.parfum1.com/pfm/hacivat-by-nishane/day-9e75cb12/full"
    }
  ]
}

Read one perfume by its handle with getPerfume:

curl -s 'https://parfum1.com/api/perfume/v1/perfumes/hacivat-by-nishane'
{
  "handle": "hacivat-by-nishane",
  "name": "Nishane Hacivat",
  "house": {
    "name": "Nishane",
    "handle": "nishane",
    "url": "https://parfum1.com/houses/nishane"
  },
  "url": "https://parfum1.com/perfume/hacivat-by-nishane",
  "api_url": "https://parfum1.com/api/perfume/v1/perfumes/hacivat-by-nishane",
  "concentration": "Extrait de Parfum",
  "family": "woody",
  "gender": "men",
  "launch_year": 2017,
  "tagline": "Pineapple, oakmoss and sunlit wood",
  "description": "Bergamot, grapefruit and pineapple open bright and sharp, then cedar, jasmine and patchouli build a woody, slightly earthy heart. Oakmoss and woody notes dry the finish. An extrait for warm nights out, with strong sillage and long-lasting wear. It is lively without being loud.",
  "notes": {
    "top": [
      "Bergamot",
      "Grapefruit",
      "Pineapple"
    ],
    "heart": [
      "Cedar",
      "Jasmine",
      "Patchouli"
    ],
    "base": [
      "Oakmoss",
      "Woody Notes"
    ]
  },
  "accords": [
    "woody",
    "citrus",
    "mossy",
    "earthy",
    "fruity",
    "sweet"
  ],
  "currency": "EUR",
  "sizes": [
    {
      "size_ml": 3,
      "price_eur": 12.15,
      "was_price_eur": 18.9,
      "price_per_ml_eur": 4.05,
      "in_stock": true
    },
    {
      "size_ml": 10,
      "price_eur": 33.39,
      "was_price_eur": 61.9,
      "price_per_ml_eur": 3.34,
      "in_stock": true
    },
    {
      "size_ml": 30,
      "price_eur": 88.2,
      "was_price_eur": 195.9,
      "price_per_ml_eur": 2.94,
      "in_stock": true
    }
  ],
  "full_bottle": {
    "size_ml": 100,
    "in_stock": false,
    "price_eur": null
  },
  "rating": {
    "value": 4.9,
    "count": 47
  },
  "images": [
    "https://img.parfum1.com/pfm/hacivat-by-nishane/day-9e75cb12/full",
    "https://img.parfum1.com/pfm/hacivat-by-nishane/golden-242b9e99/full",
    "https://img.parfum1.com/pfm/hacivat-by-nishane/spot-1c1c76f9/full"
  ]
}

What the answers contain

  • Prices are in euros and include VAT. price_eur is the price charged and was_price_eur the struck regular price shown beside it on the product page.
  • Every perfume is sold as a decant in 3, 10 and 30 ml. sizes lists each one with its price, price per ml and in_stock, as the buy box shows them.
  • The full bottle is listed on every perfume and is always out of stock, shown without a price, as on the product page.
  • notes are the top, heart and base notes and description is the text printed on the product page.
  • Every perfume and house carries its page address in url, and the answers are in English.
  • Search words must all match the perfume name, house or scent family; accents and capital letters are ignored.
  • Lists are paged: page starts at 1 and per_page goes up to 50.

Ordering happens on the website: send people to the url of the perfume.

Errors and caching

Errors are JSON with a real status code. A bad parameter is a 400, an unknown handle or path is a 404, and a catalogue that is briefly unavailable is a 503 with a Retry-After header.

{
  "error": {
    "code": "not_found",
    "message": "No perfume with the handle \"x\". Find handles with search_perfumes (GET /perfumes)."
  }
}

Successful answers are cached for an hour at the edge and served stale for a day while they refresh, so a price or a stock level can trail the product page by up to an hour. Cross-origin requests from a browser are allowed.

Discovery files

FileAddressWhat it is
OpenAPIhttps://parfum1.com/openapi.jsonOpenAPI 3.1 description of the REST API
MCP server cardhttps://parfum1.com/.well-known/mcp/server-card.jsonServer name, version, endpoint, capabilities and tools (also at /.well-known/mcp.json)
API cataloghttps://parfum1.com/.well-known/api-catalogRFC 9727 linkset listing the REST API and the MCP server with their descriptions
Agent cataloghttps://parfum1.com/.well-known/ai-catalog.jsonAgent resource catalogue with example questions for each interface
llms.txthttps://parfum1.com/llms.txtIndex of the site for agents, with Markdown copies of the help pages

This page is also available as Markdown at https://parfum1.com/developers.md.

Questions

Questions about the API or a wrong answer: write to support@parfum1.com. The data is the same catalogue the shop runs on.

Last updated 5 November 2026