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).
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.
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!
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.
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
plan
string
The name of your current subscription plan (e.g., "free", "pro").
billing_period
object
Contains the start and end dates of the current monthly billing cycle in ISO 8601 format.
limit
object
An object detailing your request limits for the current period.
total_effective_limit
integer
The total number of requests allowed this month, including any carried over from the previous period.
base_limit
integer
The standard request limit for your subscription plan, before carry-overs.
carried_over_from_previous_period
integer
The number of unused requests that were rolled over from the last billing period.
usage
object
An object detailing your request usage for the current period.
requests_made
integer
The number of requests you have made in the current billing period.
requests_remaining
integer
The 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]'
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:
Field
Type
Description
_id
string
The unique database identifier for the fragrance.
Name
string
The full name of the fragrance.
Brand
string
The brand name of the fragrance.
founder
string
The brand founder or creator attribution, verified against reliable public sources. If attribution cannot be clearly verified, this value is an empty string.
Year
string
The launch year of the fragrance.
rating
string
The rounded Bayesian rating (e.g., "4.06").
Country
string
The country of origin for the brand.
Price
string
The estimated retail price of the fragrance as a string.
Image URL
string
A direct CDN link to a standard .jpg image of the fragrance bottle.
Image URL Transparent
string
A direct CDN link to a .webp version of the bottle with a transparent background.
Gender
string
The target gender for the fragrance.
Longevity
string
A descriptive word for the scent's longevity (e.g., "Poor", "Moderate", "Long Lasting").
Sillage
string
A descriptive word for the scent's projection (e.g., "Intimate", "Moderate", "Strong").
Popularity
string
The popularity tier based on user engagement.
Price Value
string
Market sentiment regarding price suitability.
Confidence
string
The statistical trustworthiness of the performance and accord data.
OilType
string
The concentration/oil type when available.
General Notes
array
A simple list of the most prominent notes in the fragrance.
Main Accords
array
The primary scent families or accords, ordered by prominence.
Main Accords Percentage
object
A key-value map of main accords to their descriptive strength.
Notes
object
An object containing detailed notes categorized by 'Top', 'Middle', and 'Base'.
Image Fallbacks
array
(optional) An array of alternative image URLs if the primary fails.
Purchase URL
string
(optional) A direct affiliate link to purchase the fragrance.
Season Ranking
array
Ordered list (best to worst) of seasons with a suitability score.
Occasion Ranking
array
Ordered list (best to worst) of occasions with a suitability score.
The Pagination Object (Only when ?page= is used)
Field
Type
Description
page
integer
The current page number being returned.
limit
integer
The maximum number of items requested per page.
count
integer
The actual number of items returned in the data array for this page.
has_more
boolean
Returns 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
Parameter
Type
Description
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'
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
Parameter
Type
Description
accords
string
(optional) Comma-separated list of accord:minPercent Example: floral:90,citrus:60
top
string
(optional) Comma-separated list of required top notes
middle
string
(optional) Comma-separated list of required middle notes
base
string
(optional) Comma-separated list of required base notes
general
string
(optional) Comma-separated list of notes that can appear anywhere
limit
integer
(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
Parameter
Type
Description
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
Field
Type
Description
similar_to
string
The full name of the fragrance that was found and used for comparison.
similar_fragrances
array
An 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
Parameter
Type
Description
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
Parameter
Type
Description
search
string
(required) The name of the note to search for (e.g., "Bergamot"). Must be at least 2 characters.
limit
integer
(optional) Number of matches to return. Default 10, max 20.
Response Object
Field
Type
Description
name
string
The full name of the note.
occurence
integer
The number of fragrances in the database that contain this note.
description
string
A brief description of the note's scent profile.
imageUrl
string
A 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
Parameter
Type
Description
search
string
(required) The name of the accord to search for (e.g., "Woody"). Must be at least 2 characters.
limit
integer
(optional) Number of matches to return. Default 10, max 20.
Response Object
Field
Type
Description
name
string
The name of the accord.
occurence
integer
The number of fragrances in the database that feature this accord.
description
string
A 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.
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}$$
Symbol
Meaning
R
Raw average rating for that specific fragrance.
v
Number of votes (rating count) for that fragrance.
C
The global mean rating across the entire database.
m
The 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]'
[
{
"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]'
[
{
"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].