HairProfile record that captures the curl patterns, porosity levels, texture, styling goals, and hair concerns that the product is best suited for. When you call the recommendation engine, those product-side attributes are compared against the preferences you supply in your request to surface the most relevant matches.
Understanding how hair profiles are structured — and how to send one in a request — lets you build precise, personalised product discovery into your application.
Profile attributes
Each product in the database has a linkedHairProfile record. The fields below are stored as arrays because many products are suitable for a range of hair types or concerns.
The curl-pattern types this product is formulated for. Values follow the widely used André Walker typing system:
3A, 3B, 3C, 4A, 4B, 4C. A product aimed at tightly coiled hair might carry ["4A", "4B", "4C"].The porosity levels the product is best suited for. Porosity describes how readily a hair strand absorbs and retains moisture. Possible values are
low, medium, and high. Products with heavy oils or butters are often tagged ["low"] because they help seal the cuticle on hair that loses moisture quickly.The specific hair concerns the product addresses. Supported values are
dryness, breakage, growth, scalp, frizz, definition, moisture, and protein. A deep conditioner might carry ["dryness", "breakage", "moisture"].The strand thickness the product is designed for:
fine, medium, or coarse. Fine hair is easily weighed down, so this attribute helps filter out heavy creams and butters when appropriate.The styling method or routine the product supports. Examples include
wash-and-go, twist-out, and protective-styles. These map to the flags produced during AI enrichment (see Ingredient Analysis).A score between
0.0 and 1.0 indicating how certain the AI enrichment pipeline was when it classified the product’s hair profile. Scores above 0.85 indicate high confidence. Lower scores may reflect ambiguous ingredient lists or sparse product descriptions, and you may want to surface them with a lower weight in your UI.How hair profiles are used
When you callPOST /v1/recommend/, the API performs a semantic search across the product catalogue to identify the top 20 candidates whose hair profiles are most similar to the preferences you submitted. Those candidates are then passed to GPT-4o-mini, which re-ranks them based on your specific hair_type, porosity, concerns, and budget_max. The model returns a ranked list with a plain-English reason for each recommendation.
This two-stage approach — semantic search first, GPT-4o-mini re-ranking second — means results are both contextually relevant and clearly explained.
The
POST /v1/recommend/ endpoint is available on Pro and Enterprise plans only. Calling it on a Starter or Growth key returns a 403 error. See Plans & Limits for upgrade details.Passing a hair profile
Send a JSON body toPOST /v1/recommend/ with the attributes that describe your user’s hair. All fields except hair_type and porosity are optional.
Request fields
The user’s primary curl pattern. Use a single value from the André Walker typing system:
3A, 3B, 3C, 4A, 4B, or 4C.The user’s hair porosity. One of
low, medium, or high. If your users don’t know their porosity, consider linking to a porosity quiz in your onboarding flow.An array of hair concerns to prioritise during ranking. Supported values:
dryness, breakage, growth, scalp, frizz, definition, moisture, protein. Omit this field to apply no concern filter.An optional upper price bound in the currency specified by
currency. Products whose minimum price exceeds this value are excluded before re-ranking. Defaults to no limit.The currency code to apply when evaluating
budget_max. Defaults to GBP.An optional list of ingredient names to exclude. Any product whose raw ingredient list contains one of these strings (case-insensitive) is removed before re-ranking. Useful for users with known sensitivities — for example
["mineral oil", "lanolin"].The maximum number of recommendations to return. Defaults to
5. The API fetches the top 20 vector-similar candidates internally and returns up to limit after filtering and re-ranking.