API Documentation

Last Updated: May 29, 2026

Access Playground

Introduction

Welcome to the Fragella API documentation. Our API provides programmatic access to a vast database of fragrance information, perfect for powering e-commerce sites, mobile apps, or personal projects. All API endpoints are available under the base URL: https://api.fragella.com/api/v1/.

Authentication

Authentication is handled via an API key. You must include your key in the x-api-key header of every request. Requests without a valid key will be rejected.

You can get your API key by creating an account and visiting your Developer Dashboard.

Embeddable UI Widget (Headless)

Zero Backend Code Required

If you want to display Fragella data directly on your e-commerce store (like Shopify or WooCommerce) without writing any backend API logic, you can use our Headless UI widget. This approach is CSS-agnostic, meaning we only inject raw data, no styles, no fonts, no layout breaks. The data will seamlessly inherit your store's existing design. Building a custom backend? Skip directly to the API Endpoints

Works seamlessly with:
Shopify
WooCommerce
Custom HTML

1. Get Your Public Key & Set Your Domain

Go to your Developer Dashboard to find your Public Widget Key (starts with pub_). Because this key will be visible in your website's HTML, you must also set your Authorized Website Domain in the dashboard. The widget will block requests coming from unauthorized domains.

Security Warning

Never put your secret API Key in your frontend HTML. Only use your pub_ key for the widget. If you expose your secret API key, malicious users can drain your monthly request quota.

First, generate a Public Key from your Fragella Dashboard. Then, paste this lightweight script tag into your website's HTML (ideally just before the closing </body> tag of your theme).

<script src="https://cdn.fragella.com/enrich.js" data-client-id="pub_YOUR_PUBLIC_KEY"></script>
How Widget Usage is Billed

Every time the widget fetches a fragrance for a shopper on your live website, it counts as 1 request against your API monthly quota.

Built-in Optimization: Our script automatically uses sessionStorage caching. If a shopper refreshes the page or comes back to the same product later in their browsing session, the widget loads instantly from their browser cache and does not consume additional API requests.

2. How to Customize, Bind, and Style Data

To use the widget, wrap your layout in a container with the class fragella-data-container and provide the fragrance name dynamically (e.g., using Shopify Liquid {{ product.title }}).

For standard text, use data-fragella-text. For nested properties like notes, use dot-notation (e.g., Notes.Top). For arrays and objects, use data-fragella-list, which automatically generates a series of <span class="fragella-list-item"> elements that you can target with your own CSS.

<!-- 1. The Container -->
<div class="fragella-data-container" data-fragrance-name="{{ product.title }}">
    
    <!-- Simple Text & Images -->
    <img data-fragella-image="Image URL" alt="Bottle" class="product-img" />
    <p><strong>Type:</strong> <span data-fragella-text="OilType"></span></p>
    <p><strong>Founder/creator:</strong> <span data-fragella-text="founder"></span></p>
    
    <!-- Nested Array/List Data -->
    <h4>Top Notes</h4>
    <div data-fragella-list="Notes.Top" class="my-notes-wrapper"></div>

    <h4>Accords & Strengths</h4>
    <div data-fragella-list="Main Accords Percentage" class="my-accords-wrapper"></div>

</div>

<!-- 2. Your Custom CSS (Style the injected spans) -->
<style>
    /* Style the generated list items based on their parent wrapper */
    .my-notes-wrapper .fragella-list-item {
        background-color: #f3f4f6;
        padding: 4px 8px;
        border-radius: 4px;
        margin-right: 4px;
    }
    .my-accords-wrapper .fragella-list-item {
        background-color: #1E3932;
        color: white;
        padding: 4px 10px;
        border-radius: 9999px; /* Pill shape */
        margin-right: 4px;
    }
</style>

<!-- 3. Load the script -->
<script src="https://cdn.fragella.com/enrich.js" data-client-id="pub_YOUR_PUBLIC_KEY"></script>

Free Pre-Built Widget Themes

Skip writing CSS and copy/paste our ready-to-use templates (Dark Mode, Minimalist, etc.). Submit your own custom theme to [email protected] to win a $20 bounty!

Browse Themes

2.1 Error Handling & Security Checks

Because the Headless Widget executes in the browser, it relies on strict security and quota checks. Here is what happens if a request is rejected:

Domain Not Whitelisted

Your pub_ key is strictly locked to the exact URLs you register in your dashboard. If the widget is loaded on an unauthorized domain, the API will immediately block the request to prevent key theft.

Quota Exhausted

If your account exceeds its monthly request limit, the API will return a 429 Too Many Requests status until your billing cycle resets or you upgrade your plan.

Subdomains & Local Testing: While limited to one primary domain, you can safely use the widget across its subdomains (e.g., shop.mystore.com) and your local development environments (e.g., localhost:3000). Just make sure to explicitly add your main production domain, along with any necessary subdomains, to your dashboard's CORS whitelist.

Crucial Security Warning: While testing on localhost is fully supported, you must remove it from your whitelist before going to production. If left active, a malicious user could copy your public key from your live site and drain your monthly API quota from their own local machine.

Graceful Failures: The widget is designed to fail gracefully. Whether an API request is blocked, or a fragrance simply isn't in our database yet, your website's layout will not break. Standard text fields will default to reading Not Found, and missing images or accord lists will safely remain hidden.

3. Interactive Live Preview

Type a fragrance name below and hit test. On the left is the live rendered result, and on the right is the exact HTML and CSS powering it.

Fragrance Bottle

Loading... Founder/creator: Loading... Loading...

Released: ...

Longevity Loading...
Sillage Loading...
Type Loading...
Rating .../5.0
Top Notes
Fetching notes...
Main Accords
Fetching accords...
The HTML behind the card
<div class="fragella-data-container" data-fragrance-name="Eau Sauvage">
    
  <!-- Image & Titles -->
  <img data-fragella-image="Image URL" />
  <span data-fragella-text="Brand"></span>
  <span data-fragella-text="founder"></span>
  <span data-fragella-text="Name"></span>
    
  <!-- Performance Stats -->
  <span data-fragella-text="Longevity"></span>
  <span data-fragella-text="Sillage"></span>
  <span data-fragella-text="OilType"></span>
  <span data-fragella-text="rating"></span>

  <!-- Array Lists (Outputs as spans) -->
  <div data-fragella-list="Notes.Top"></div>
  <div data-fragella-list="Main Accords Percentage"></div>

  <!-- CSS targeting the generated spans -->
  <style>
    [data-fragella-list="Notes.Top"] .fragella-list-item {
        background-color: #f3f4f6;
        border-radius: 9999px;
    }
    [data-fragella-list="Main Accords Percentage"] .fragella-list-item {
        background-color: #1E3932;
        color: white;
    }
  </style>
</div>
<!-- Load the script -->
<script src="https://cdn.fragella.com/enrich.js" data-client-id="pub_test_12345"></script>

Available Data Fields

You can use any of the following values inside the data-fragella-text or data-fragella-list attributes exactly as they are written (case-sensitive).

Field Attribute Attribute Type What Gets Injected
founder data-fragella-text Verified brand founder/creator attribution, or an empty string when unresolved
Longevity data-fragella-text Descriptive word (e.g., "Long Lasting", "Moderate")
Sillage data-fragella-text Descriptive word (e.g., "Strong", "Intimate")
Gender data-fragella-text Target gender (e.g., "women", "men", "unisex")
OilType data-fragella-text Concentration (e.g., "Eau de Parfum", "Eau de Toilette")
Popularity data-fragella-text Engagement tier (e.g., "Very high", "Medium")
Price Value data-fragella-text Market sentiment on price (e.g., "good_value", "overpriced")
Confidence data-fragella-text Statistical trustworthiness (e.g., "high", "medium")
rating data-fragella-text Bayesian rating out of 5.00 (e.g., "4.32")
Notes.Top data-fragella-text Comma-separated top notes (e.g., "Lemon, Bergamot")
Notes.Middle data-fragella-text Comma-separated middle notes (e.g., "Jasmine, Coriander")
Notes.Base data-fragella-text Comma-separated base notes (e.g., "Oakmoss, Vetiver")
Main Accords Percentage data-fragella-text Comma-separated list of accords with their strength
Main Accords data-fragella-list Injects multiple spans for you to style via CSS.
General Notes data-fragella-list Injects multiple spans containing prominent notes.
Notes.Top data-fragella-list Injects each top note as a stylable span element.
Notes.Middle data-fragella-list Injects each middle note as a stylable span element.
Notes.Base data-fragella-list Injects each base note as a stylable span element.
Main Accords Percentage data-fragella-list Injects spans formatted as "Accord (Strength)".
Image URL data-fragella-image Sets the src attribute to the bottle picture.
Image URL Transparent data-fragella-image Sets the src attribute to the transparent .webp version.

Endpoints

Working with Images: The API provides two image fields: Image URL (standard .jpg with a solid background) and Image URL Transparent (a .webp file with the background removed). This does not apply to the Image Fallbacks array.

GET /usage

Check the current status of your API key's monthly quota. This endpoint provides a detailed breakdown of your current plan, usage, and billing cycle.

Request Parameters

This endpoint does not require any query parameters. Authentication is handled via the standard x-api-key header.

Response Object

Field Type Description
planstringThe name of your current subscription plan (e.g., "free", "pro").
billing_periodobjectContains the start and end dates of the current monthly billing cycle in ISO 8601 format.
limitobjectAn object detailing your request limits for the current period.
total_effective_limitintegerThe total number of requests allowed this month, including any carried over from the previous period.
base_limitintegerThe standard request limit for your subscription plan, before carry-overs.
carried_over_from_previous_periodintegerThe number of unused requests that were rolled over from the last billing period.
usageobjectAn object detailing your request usage for the current period.
requests_madeintegerThe number of requests you have made in the current billing period.
requests_remainingintegerThe number of requests you have left for the current billing period.

Example Request & Response

Here is an example of how to call the endpoint and the structure of the data you will receive.

curl --request GET \
  --url 'https://api.fragella.com/api/v1/usage' \
  --header 'x-api-key: [your-api-key]'

Sample Response

{
  "plan": "pro",
  "billing_period": {
      "start": "2025-09-01T15:36:00.000Z",
      "end": "2025-10-01T15:35:59.999Z"
  },
  "limit": {
      "total_effective_limit": 11500,
      "base_limit": 20000,
      "carried_over_from_previous_period": 1500
  },
  "usage": {
      "requests_made": 4250,
      "requests_remaining": 7250
  }
}

GET /fragrances

This is the primary endpoint for searching the fragrance database. The search is powered by a case-insensitive, fuzzy-matching algorithm, so an exact query is not required to get relevant results. If the limit parameter is not provided, a default of 5 results will be returned.

The default limit is intentionally kept small to help prevent abuse, reduce unnecessary load on the API, and keep response times fast. In most fragrance search use cases, users already know the fragrance, brand, note, or accord they are searching for, so a small set of relevant results is usually enough. Clients may increase the limit when they need more results, but most searches should not require paging through a large number of entries.

Request Parameters

Parameter Type Description
search string (required) The name of the fragrance or brand. Must be at least 3 characters long.
page integer (optional) The page number to retrieve. If provided, the response changes to a paginated object. Max depth is 5 pages.
limit integer (optional) The number of results to return. Defaults to 5. Maximum value is 10.

Response Object

Each fragrance object returned by the API contains the following fields:

Dual Response Format

To maintain backward compatibility for existing integrations, this endpoint returns a flat JSON array of fragrances by default.

However, if you explicitly include the page parameter in your request (e.g., &page=1), the API will return a Paginated Object containing a data array and a pagination metadata object.

The Fragrance Object

Whether returned inside a flat array or inside the paginated data array, each fragrance object contains the following fields:

FieldTypeDescription
_idstringThe unique database identifier for the fragrance.
NamestringThe full name of the fragrance.
BrandstringThe brand name of the fragrance.
founderstringThe brand founder or creator attribution, verified against reliable public sources. If attribution cannot be clearly verified, this value is an empty string.
YearstringThe launch year of the fragrance.
ratingstringThe rounded Bayesian rating (e.g., "4.06").
CountrystringThe country of origin for the brand.
PricestringThe estimated retail price of the fragrance as a string.
Image URLstringA direct CDN link to a standard .jpg image of the fragrance bottle.
Image URL TransparentstringA direct CDN link to a .webp version of the bottle with a transparent background.
GenderstringThe target gender for the fragrance.
LongevitystringA descriptive word for the scent's longevity (e.g., "Poor", "Moderate", "Long Lasting").
SillagestringA descriptive word for the scent's projection (e.g., "Intimate", "Moderate", "Strong").
PopularitystringThe popularity tier based on user engagement.
Price ValuestringMarket sentiment regarding price suitability.
ConfidencestringThe statistical trustworthiness of the performance and accord data.
OilTypestringThe concentration/oil type when available.
General NotesarrayA simple list of the most prominent notes in the fragrance.
Main AccordsarrayThe primary scent families or accords, ordered by prominence.
Main Accords PercentageobjectA key-value map of main accords to their descriptive strength.
NotesobjectAn object containing detailed notes categorized by 'Top', 'Middle', and 'Base'.
Image Fallbacksarray(optional) An array of alternative image URLs if the primary fails.
Purchase URLstring(optional) A direct affiliate link to purchase the fragrance.
Season RankingarrayOrdered list (best to worst) of seasons with a suitability score.
Occasion RankingarrayOrdered list (best to worst) of occasions with a suitability score.
The Pagination Object (Only when ?page= is used)
FieldTypeDescription
pageintegerThe current page number being returned.
limitintegerThe maximum number of items requested per page.
countintegerThe actual number of items returned in the data array for this page.
has_morebooleanReturns true if there is another page of results available.

GET /fragrances/:id

Retrieves the full profile of a single fragrance using its unique identifier (slug).

Request Parameters

ParameterTypeDescription
id string (required) The specific _id slug of the fragrance (e.g., "eau-sauvage"). Passed in the URL path.

Example Request

curl --request GET \
  --url 'https://api.fragella.com/api/v1/fragrances/eau-sauvage' \
  --header 'x-api-key: YOUR_API_KEY'

GET /fragrances/match

Returns fragrances that satisfy all requested accords and notes. You can combine minimum accord percentages with specific top, middle, base, or general notes. Results are ranked by best overall fit. If limit is omitted, the top 10 matches are returned.

Request Parameters

ParameterTypeDescription
accords string (optional) Comma-separated list of accord:minPercent Example: floral:90,citrus:60
topstring(optional) Comma-separated list of required top notes
middlestring(optional) Comma-separated list of required middle notes
basestring(optional) Comma-separated list of required base notes
generalstring(optional) Comma-separated list of notes that can appear anywhere
limitinteger(optional) Number of matches to return. Default 10, max 10.

GET /fragrances/similar

Finds fragrances that are most similar to a given scent. The API first performs a fuzzy search to find the best match for the provided name, then scores all other fragrances against it based on shared accords (primary) and notes (secondary).

Request Parameters

ParameterTypeDescription
name string (required) The name of the fragrance to use as a base for comparison.
limit integer (optional) Number of similar matches to return. Default 10, max 10.

Response Object

FieldTypeDescription
similar_tostringThe full name of the fragrance that was found and used for comparison.
similar_fragrancesarrayAn array of the most similar fragrances, sorted by score. Each object contains the full standard fragrance response plus the SimilarityScore.

GET /brands/:brandName

Retrieves all fragrances associated with a specific brand. The brand name is provided as a path parameter and is case-insensitive. This is the ideal endpoint for creating brand-specific pages or listings.

Request Parameters

ParameterTypeDescription
brandName string (required) The name of the brand to search for (e.g., "Dior"). Passed in the URL path.
limit integer (optional) The number of results to return. Defaults to 10. Maximum value is 50.

GET /notes

Searches the database for individual fragrance notes. This allows you to retrieve details about specific notes, such as their scent profile and how frequently they are used.

Request Parameters

ParameterTypeDescription
searchstring (required) The name of the note to search for (e.g., "Bergamot"). Must be at least 2 characters.
limitinteger (optional) Number of matches to return. Default 10, max 20.

Response Object

FieldTypeDescription
namestringThe full name of the note.
occurenceintegerThe number of fragrances in the database that contain this note.
descriptionstringA brief description of the note's scent profile.
imageUrlstringA direct CDN link to an image representing the note.

GET /accords

Searches the database for fragrance accords (scent families). This is useful for understanding the primary character of different fragrances.

Request Parameters

ParameterTypeDescription
searchstring (required) The name of the accord to search for (e.g., "Woody"). Must be at least 2 characters.
limitinteger (optional) Number of matches to return. Default 10, max 20.

Response Object

FieldTypeDescription
namestringThe name of the accord.
occurenceintegerThe number of fragrances in the database that feature this accord.
descriptionstringA brief description of the accord.

Data Methodology

Understanding Descriptive Fields

To make the API more user-friendly, fields like Longevity, Sillage, and Main Accords Percentage return descriptive words instead of raw percentages. Here is a guide to what those values represent.

Longevity Values
  • Very Long Lasting: Scent lasts over 12 hours.
  • Long Lasting: Scent lasts between 8-12 hours.
  • Moderate: Scent lasts between 4-7 hours.
  • Weak: Scent lasts between 2-3 hours.
  • Poor: Scent lasts less than 2 hours.
Sillage Values
  • Enormous: Fills a room; projection is very heavy.
  • Strong: Projects beyond arm's length; easily noticed.
  • Moderate: Projects to about arm's length.
  • Soft: Sits closer to the skin, but is noticeable.
  • Intimate: Sits very close to the skin.

Understanding Market Intelligence

These fields provide technical insights into data reliability and market positioning based on user voting data.

Popularity Tiers (frag_popularity)

Based on the total number of users who have interacted with the fragrance:

  • Very high: 1,000+ users.
  • High: 200 - 999 users.
  • Medium: 30 - 199 users.
  • Low: 1 - 29 users (matches CLT "small n" criteria).
  • Not popular: 0 users.
Price Value (price_value)

Determined by the largest vote bucket among users:

  • good_value: The "good value" bucket is the largest.
  • okay: The "okay" bucket is the largest.
  • overpriced: The "overpriced" bucket is the largest.
  • unknown: Total votes = 0.
Confidence (confidence)

Reflects the trustworthiness of the data based on sample size and statistical separation:

  • high: Votes ≥ 100 and separation between winner and runner-up is very clear (z ≥ 3).
  • medium: Votes ≥ 30 and separation is statistically decent (z ≥ 1.96).
  • low: Total votes < 30, OR winner vs runner-up is not clearly separated.

Bayesian Rating Calculation

The rating field in the Fragella API uses Bayesian Weighted Ratings. This is the same logic used by major platforms to ensure that a fragrance with a few 5-star reviews doesn't unfairly outrank a legendary fragrance with thousands of 4.5-star reviews.

$$Bayesian\ Rating = \frac{R \cdot v + C \cdot m}{v + m}$$

SymbolMeaning
RRaw average rating for that specific fragrance.
vNumber of votes (rating count) for that fragrance.
CThe global mean rating across the entire database.
mThe smoothing constant (minimum votes threshold fixed at 500).

How Descriptive Values Are Determined

The descriptive terms for Longevity, Sillage, and Accord Strength are derived from aggregating and analyzing perception data from a wide range of users across fragrance communities. We process these inputs to establish a statistical distribution for each metric across our entire database (tens of thousands of fragrances).

Similarly, the notes and main accords listed for each fragrance are determined through a combination of methods. We utilize AI models trained on official brand descriptions and expert reviews, supplemented and refined by aggregated user input from large fragrance communities.

Data Completeness & Gap Filling

We are committed to providing the most comprehensive dataset available. Our data is sourced primarily from aggregated user input across large fragrance communities. For fields where this data is sparse, we employ machine learning models to analyze related data and predict missing values (like Accords and Notes) with an estimated 80% confidence level.

As of our last database review, our fill-rates for key fields are as follows:

  • Notes & Main Accords: 100% complete.
  • Price: Most current values are estimates, and we are actively working to provide more accurate and comprehensive data.
  • Purchase URL: These links may include affiliate URLs or other retailers we've found.

Examples & Responses

Example 1: Searching for Multiple Results

A search for "Viva La Juicy" returns an array of all fragrances matching the term.

curl --request GET \
  --url 'https://api.fragella.com/api/v1/fragrances?search=Viva%20La%20Juicy' \
  --header 'x-api-key: [api-key]'
Sample Response: "Viva La Juicy"
[
    {
        "_id": "viva-la-juicy",
        "Name": "Viva La Juicy",
        "Brand": "Juicy Couture",
        "founder": "Pamela Skaist-Levy & Gela Nash-Taylor",
        "Year": "2008",
        "rating": "4",
        "Country": "USA",
        "Popularity": "Very high",
        "Price Value": "good_value",
        "Confidence": "high",
        "Image URL": "https://cdn.fragella.com/images/viva-la-juicy.jpg",
        "Image URL Transparent": "https://cdn.fragella.com/images/viva-la-juicy.webp",
        "Gender": "women",
        "Price": "79.99",
        "Longevity": "Moderate", 
        "Sillage": "Moderate",      
        "OilType": "Eau de Parfum", 
        "Season Ranking": [
           { "name": "spring",  "score": 2.384 },
           { "name": "fall",    "score": 2.066 },
           { "name": "summer",  "score": 2.019 },
           { "name": "winter",  "score": 1.120 }
        ],
       "Occasion Ranking": [
         { "name": "casual",       "score": 2.980 },
         { "name": "night out",    "score": 1.418 },
         { "name": "professional", "score": 1.192 }
       ],
        "General Notes": ["honeysuckle", "vanilla", "caramel", "amber", "sandalwood", "mandarin orange"],
        "Main Accords": ["sweet", "white floral", "caramel", "fruity", "vanilla", "citrus", "woody", "lactonic", "amber", "powdery"],
        "Main Accords Percentage": { 
            "sweet": "Dominant",
            "white floral": "Dominant",
            "caramel": "Prominent",
            "fruity": "Prominent",
            "vanilla": "Prominent",
            "citrus": "Prominent",
            "woody": "Moderate",
            "lactonic": "Moderate",
            "amber": "Subtle",
            "powdery": "Subtle"
        },
        "Notes": {
            "Top": [{"name": "Lemon", "imageUrl": "..."}, {"name": "Bergamot", "imageUrl": "..."}],
            "Middle": [{"name": "Jasmine", "imageUrl": "..."}, {"name": "Coriander", "imageUrl": "..."}],
            "Base": [{"name": "Oakmoss", "imageUrl": "..."}, {"name": "Vetiver", "imageUrl": "..."}]
        },
        "Image Fallbacks": [
            "https://..."
        ],
        "Purchase URL": "https://..."
    },
    {
        "_id": "viva-la-juicy-rose",
        "Name": "Viva La Juicy Rose",
        "Brand": "Juicy Couture",
        "founder": "Pamela Skaist-Levy & Gela Nash-Taylor",
        "Year": "2008",
        "rating": "4",
        "Country": "USA",
        "Popularity": "Very high",
        "Price Value": "good_value",
        "Confidence": "high",
        "Image URL": "https://cdn.fragella.com/images/viva-la-juicy-rose.jpg",
        "Image URL Transparent": "https://cdn.fragella.com/images/viva-la-juicy.webp",
        "Gender": "women",
        "Price": "56.99",
        "Longevity": "Moderate", 
        "Sillage": "Moderate", 
        "OilType": "Eau de Parfum",
        "Main Accords": ["rose", "floral", "fresh", "fruity", "citrus", "amber", "sweet", "white floral", "aquatic"],
        "Notes": { /* ... notes object ... */ },
        "Image Fallbacks": [
            "https://..."
        ],
        "Purchase URL": "https://..."
    },
    {
        "_id": "viva-la-juicy",
        "Name": "Viva La Juicy Glace",
        "Brand": "Juicy Couture",
        "founder": "Pamela Skaist-Levy & Gela Nash-Taylor",
        "Image URL": "https://cdn.fragella.com/images/viva-la-juicy-glace.jpg",
        "Image URL Transparent": "https://cdn.fragella.com/images/viva-la-juicy.webp",
        "Gender": "women",
        "Year": "2008",
        "rating": "4",
        "Country": "USA",
        "Price": "61.99",
        "Popularity": "Very high",
        "Price Value": "good_value",
        "Confidence": "high",
        "Longevity": "Moderate", 
        "Sillage": "Moderate", 
        "OilType": "Eau de Parfum",
        "Season Ranking": [
           { "name": "spring",  "score": 2.384 },
           { "name": "fall",    "score": 2.066 },
           { "name": "summer",  "score": 2.019 },
           { "name": "winter",  "score": 1.120 }
        ],
       "Occasion Ranking": [
         { "name": "casual",       "score": 2.980 },
         { "name": "night out",    "score": 1.418 },
         { "name": "professional", "score": 1.192 }
       ],
        "Main Accords": ["sweet", "fruity", "vanilla", "fresh", "aquatic", "powdery", "white floral"],
        "Notes": { /* ... notes object ... */ },
        "Image Fallbacks": [
            "https://..."
        ],
        "Purchase URL": "https://..."
    }
    /* ... more results */
]

Example 2: Limiting to a Single Result

Use the limit=1 parameter to get only the most relevant result.

curl --request GET \
  --url 'https://api.fragella.com/api/v1/fragrances?search=Sauvage&limit=1' \
  --header 'x-api-key: [api-key]'
Sample Response: "Sauvage" with limit=1
[
    {
        "_id": "EauSauvage",
        "Name": "Eau Sauvage",
        "Brand": "Christian Dior",
        "founder": "Christian Dior",
        "Year": "1966",
        "rating": "4",
        "Popularity": "High",
        "Price Value": "overpriced",
        "Confidence": "high",
        "Country": "France",
        "Image URL": "https://cdn.fragella.com/images/eau-sauvage.jpg",
        "Image URL Transparent": "https://cdn.fragella.com/images/eau-sauvage.webp",
        "Gender": "men",
        "Price": "152.99",
        "Longevity": "Moderate", 
        "Sillage": "Moderate",
        "OilType": "Eau de Toilette",
        "Season Ranking": [
           { "name": "spring",  "score": 2.384 },
           { "name": "fall",    "score": 2.066 },
           { "name": "summer",  "score": 2.019 },
           { "name": "winter",  "score": 1.120 }
        ],
       "Occasion Ranking": [
         { "name": "casual",       "score": 2.980 },
         { "name": "night out",    "score": 1.418 },
         { "name": "professional", "score": 1.192 }
       ],
        "General Notes": ["Hedione", "Galbanum", "Petitgrain", "Vetiver", "Pink Pepper"],
        "Main Accords": ["aromatic", "citrus", "fresh spicy", "woody", "earthy", "mossy", "green", "floral"],
        "Main Accords Percentage": {
            "aromatic": "Dominant",
            "citrus": "Dominant",
            "fresh spicy": "Prominent",
            "woody": "Prominent",
            "earthy": "Moderate",
            "mossy": "Subtle",
            "green": "Subtle",
            "floral": "Subtle"
        },
        "Notes": {
            "Top": [{"name": "Lemon", "imageUrl": "..."}, {"name": "Bergamot", "imageUrl": "..."}],
            "Middle": [{"name": "Jasmine", "imageUrl": "..."}, {"name": "Coriander", "imageUrl": "..."}],
            "Base": [{"name": "Oakmoss", "imageUrl": "..."}, {"name": "Vetiver", "imageUrl": "..."}]
        },
        "Image Fallbacks": [
            "https://..."
        ],
        "Purchase URL": "https://..."
    }
]

Example 2.1: Paginated Search

By including the page parameter, the API wraps the results in a pagination object, allowing you to build "Load More" functionality.

curl --request GET \
  --url 'https://api.fragella.com/api/v1/fragrances?search=Sauvage&limit=2&page=1' \
  --header 'x-api-key: [api-key]'
Sample Response (Paginated)
{
  "data": [
    {
        "_id": "EauSauvage",
        "Name": "Eau Sauvage",
        "Brand": "Christian Dior",
        "founder": "Christian Dior",
        "Year": "1966"
        /* ... remaining fragrance fields ... */
    },
    {
        "_id": "Sauvage",
        "Name": "Sauvage",
        "Brand": "Christian Dior",
        "founder": "Christian Dior",
        "Year": "2015"
        /* ... remaining fragrance fields ... */
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 2,
    "count": 2,
    "has_more": true
  }
}

Example 3: Accord + Note Matching

Find fragrances that are at least 100 % floral, 90 % fruity, and 80 % citrus, with specific top, middle, and base notes.

curl --request GET \
  --url 'https://api.fragella.com/api/v1/fragrances/match?accords=floral:100,fruity:90,citrus:80&top=Pear,Bitter%20Orange,Bergamot&middle=Freesia&base=Iso%20E%20Super&limit=3' \
  --header 'x-api-key: [api-key]'
Sample Response
[
  {
    "_id": "Versace-Dylan-Purple",
    "Name": "Versace Dylan Purple",
    "Brand": "Gianni Versace",
    "founder": "Gianni Versace",
    "Image URL": "https://cdn.fragella.com/images/versace-dylan-purple.jpg",
    "Image URL Transparent": "https://cdn.fragella.com/images/versace-dylan-purple.webp",
    "Gender": "women",
    "Price": "114.99",
    "Year": "2022",
    "Popularity": "Medium",
    "Price Value": "okay",
    "Confidence": "medium",
    "rating": "4",
    "Country": "Italy",
    "Longevity": "Moderate", 
    "Sillage": "Moderate", 
    "OilType": "Eau de Toilette",
    "Season Ranking": [
           { "name": "spring",  "score": 2.384 },
           { "name": "fall",    "score": 2.066 },
           { "name": "summer",  "score": 2.019 },
           { "name": "winter",  "score": 1.120 }
        ],
    "Occasion Ranking": [
         { "name": "casual",       "score": 2.980 },
         { "name": "night out",    "score": 1.418 },
         { "name": "professional", "score": 1.192 }
       ],
    "General Notes": ["Pear","Bitter Orange","Bergamot","Freesia","Pomarose","Mahonial","Iso E Super","Ambroxan","Sylkolide","Virginia Cedar","Belambra tree"],
    "Main Accords": ["floral","fruity","citrus","amber","woody","musky","sweet","fresh","aquatic","fresh spicy"],
    "Main Accords Percentage": {
      "floral":"Dominant",
      "fruity":"Dominant",
      "citrus":"Dominant",
      "amber":"Prominent",
      "woody":"Prominent",
      "musky":"Prominent",
      "sweet":"Prominent",
      "fresh":"Prominent",
      "aquatic":"Prominent",
      "fresh spicy":"Subtle"
    },
    "Notes": { /* ... */ },
    "Image Fallbacks": [
            "https://..."
        ],
    "Purchase URL": "https://..."
  }
]

Example 4: Finding Similar Fragrances

Find the top 3 fragrances most similar to "Sauvage". The API finds the best match for "Sauvage" (which is "Dior Sauvage") and returns the results.

curl --request GET \
  --url 'https://api.fragella.com/api/v1/fragrances/similar?name=Sauvage&limit=3' \
  --header 'x-api-key: [api-key]'
Sample Response
{
  "similar_to": "Dior Sauvage",
  "similar_fragrances": [
    {
      "_id": "Prada-Luna-Rossa-Carbon",
      "Name": "Prada Luna Rossa Carbon",
      "Brand": "Prada",
      "founder": "Mario Prada & Martino Prada",
      "Year": "2017",
      "rating": "4",
      "Country": "Italy",
      "Popularity": "Medium",
      "Price Value": "okay",
      "Confidence": "medium",
      "Longevity": "Long Lasting", 
      "Sillage": "Strong",      
      "OilType": "Eau de Toilette", 
      "General Notes": ["Bergamot", "Lavender", "Ambroxan"],
      "Main Accords": ["aromatic", "fresh spicy", "citrus", "musky"],
      "Notes": { /* ... */ },
      "Purchase URL": "https://...",
      // ... all other fragrance properties ...
      "SimilarityScore": 0.8912
    },
    {
      "_id": "Versace-Dylan-Blue",
      "Name": "Versace Dylan Blue",
      "Brand": "Gianni Versace",
      "founder": "Gianni Versace",
      "Year": "2016",
      "rating": "4",
      "Country": "Italy",
      "Popularity": "Medium",
      "Price Value": "okay",
      "Confidence": "medium",
      "Longevity": "Long Lasting", 
      "Sillage": "Strong",      
      "OilType": "Eau de Toilette", 
      "General Notes": ["Ambroxan", "Grapefruit", "Incense"],
      "Main Accords": ["amber", "aquatic", "citrus", "incense"],
      "Notes": { /* ... */ },
      "Purchase URL": "https://...",
      // ... all other fragrance properties ...
      "SimilarityScore": 0.7645
    }
  ]
}

Example 5: Searching by Brand

Find the top 5 fragrances from the brand "Dior".

curl --request GET \
  --url 'https://api.fragella.com/api/v1/brands/Dior?limit=5' \
  --header 'x-api-key: [api-key]'
Sample Response
[
    {
        "_id": "Chirstian-Dior-Eau-Sauvage-Edt",
        "Name": "Chirstian Dior Eau Sauvage Edt",
        "Brand": "Dior",
        "founder": "Christian Dior",
        "Year": "1966",
        "rating": "4",
        "Country": "France",
        "Popularity": "Medium",
        "Price Value": "okay",
        "Confidence": "medium",
        "Image URL": "https://cdn.fragella.com/images/chirstian-dior-eau-sauvage-edt.jpg",
        "Image URL Transparent": "https://cdn.fragella.com/images/chirstian-dior-eau-sauvage-edt.webp",
        "Gender": "Men",
        "Price": "69.00",
        "OilType": "",
        "Notes": {
            "Top": [{"name": "Lemon", "imageUrl": "..."}, {"name": "Bergamot", "imageUrl": "..."}],
            "Middle": [{"name": "Jasmine", "imageUrl": "..."}, {"name": "Coriander", "imageUrl": "..."}],
            "Base": [{"name": "Oakmoss", "imageUrl": "..."}, {"name": "Vetiver", "imageUrl": "..."}]
        }
        /* ... other fragrance fields ... */
    },
    {
        "_id": "Christian-Dior-Dior-Sauvage-Edp",
        "Name": "Christian Dior Dior Sauvage Edp",
        "Brand": "Dior",
        "founder": "Christian Dior",
        "Image URL": "https://cdn.fragella.com/images/christian-dior-dior-sauvage-edp.jpg",
        "Gender": "Men",
        "Price": "85.00",
        "Notes": { /* ... */ }
        /* ... other fragrance fields ... */
    }
    /* ... more results up to the limit ... */
]

Example 6: Searching for Notes

Find notes matching the term "Bergamot", limited to 3 results.

curl --request GET \
  --url 'https://api.fragella.com/api/v1/notes?search=Bergamot&limit=3' \
  --header 'x-api-key: [api-key]'
Sample Response
[
    {
        "name": "Bergamot",
        "occurence": 3549,
        "description": "Bergamot offers a bright, uplifting citrus scent with subtle floral undertones. It's commonly used as a top note to add freshness and vitality to perfumes.",
        "imageUrl": "https://cdn.fragella.com/note_images/Bergamot.png"
    },
    {
        "name": "Sicilian Bergamot",
        "occurence": 55,
        "description": "Sicilian Bergamot is a brighter, slightly sweeter, and less bitter citrus scent compared to Calabrian Bergamot, offering a sparkling and uplifting top note.",
        "imageUrl": "https://cdn.fragella.com/note_images/Sicilian%20Bergamot.png"
    },
    {
        "name": "White Bergamot",
        "occurence": 2,
        "description": "White Bergamot offers a light, fresh, and subtly sweet citrus scent, cleaner and less tart than traditional bergamot, with an ethereal radiance.",
        "imageUrl": "https://cdn.fragella.com/note_images/White%20Bergamot.png"
    }
]

Example 7: Searching for Accords

Find accords matching the term "Woody".

curl --request GET \
  --url 'https://api.fragella.com/api/v1/accords?search=Woody&limit=4' \
  --header 'x-api-key: [api-key]'
Sample Response
[
    {
        "name": "woody",
        "occurence": 8234,
        "description": "Woody accords are rich and warm, often evoking the scent of various woods like sandalwood, cedar, and vetiver. They provide depth and longevity to fragrances, making them a staple in many perfumes."
    }
]

Error Handling

The API uses conventional HTTP status codes to indicate the success or failure of a request.

Status Code Meaning Reason
200 OK Success The request was successful.
400 Bad Request Invalid Parameter A required parameter is missing or fails validation.
401 Unauthorized Authentication Error Your API key is missing from the header.
403 Forbidden Authentication Error Your API key is invalid or incorrect.
404 Not Found Not Found No fragrances were found matching your search query.
429 Too Many Requests Rate Limit Exceeded You have exceeded the request limit for your current subscription plan.
500 Internal Server Error Server Error Something went wrong on our end. Please try again later.

Support

If you find anything wrong, notice something is missing, or have any problems, please don't hesitate to contact us at [email protected].

© 2026 Fragella™ All rights reserved.