Recommendation API - Sommelier du Parfum v1.0
Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.
Welcome to Sommelier du Parfum's Recommendation API.
This API documentation is interactive: you can run real queries again the test (or production) API. To do so, first click on the Authorize button and fill your token in. Then, click on any "Try it out" button to test a route.
The main route is /compute_recommendation and allows you to retrieve a recommendation set, given a user preferences model.
Test API
There is a test API, which differs slightly from the production API:
- you can find a valid test token in the Authentication section below
- all routes return static results, that are real-world examples
Authentication
Authentication is performed via an HTTP header: Bearer: token
This token is provided by Sommelier du Parfum and should be renewed every year.
Note: you can use the following token for the test API (on the right):
Bearer: QT`N;~()W}j?/cnvN0PYn9
Base URLs:
Authentication
- HTTP Authentication, scheme: bearer
RecommendationEngine
post__compute_recommendation
Code samples
# You can also use wget
curl -X POST https://test-api.sommelier.tech/v1.0//compute_recommendation \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer {access-token}'
POST https://test-api.sommelier.tech/v1.0//compute_recommendation HTTP/1.1
Host: test-api.sommelier.tech
Content-Type: application/json
Accept: application/json
var headers = {
'Content-Type':'application/json',
'Accept':'application/json',
'Authorization':'Bearer {access-token}'
};
$.ajax({
url: 'https://test-api.sommelier.tech/v1.0//compute_recommendation',
method: 'post',
headers: headers,
success: function(data) {
console.log(JSON.stringify(data));
}
})
const request = require('node-fetch');
const inputBody = '{
"type": "object",
"required": [
"gender",
"perfumes_liked"
],
"properties": {
"perfumes_liked": {
"description": "List of perfume IDs liked by the user",
"type": "array",
"example": [
"EAR9JSFYP0",
"ABCDEFGHIJ"
],
"items": {
"type": "string",
"description": "Perfume ID"
}
},
"gender": {
"type": "string",
"description": "The user gender.",
"enum": [
"male",
"female",
"other"
]
},
"age": {
"type": "number",
"format": "int",
"nullable": true,
"example": 26,
"description": "The user age."
},
"restrict_to_store_id": {
"type": "string",
"nullable": true,
"example": "4242",
"description": "Restrict the recommendation to perfumes available in this store.\n"
},
"is_gift": {
"description": "Will this perfume be given to someone else as a gift?",
"type": "boolean",
"default": false
}
}
}';
const headers = {
'Content-Type':'application/json',
'Accept':'application/json',
'Authorization':'Bearer {access-token}'
};
fetch('https://test-api.sommelier.tech/v1.0//compute_recommendation',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Bearer {access-token}'
}
result = RestClient.post 'https://test-api.sommelier.tech/v1.0//compute_recommendation',
params: {
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer {access-token}'
}
r = requests.post('https://test-api.sommelier.tech/v1.0//compute_recommendation', params={
}, headers = headers)
print r.json()
URL obj = new URL("https://test-api.sommelier.tech/v1.0//compute_recommendation");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer {access-token}"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("POST", "https://test-api.sommelier.tech/v1.0//compute_recommendation", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
POST /compute_recommendation
Retrieve the recommendation for a given preferences set.
Use Sommelier du Parfum's recommendation engine to select the perfumes that the user will most likely like.
Body parameter
{
"type": "object",
"required": [
"gender",
"perfumes_liked"
],
"properties": {
"perfumes_liked": {
"description": "List of perfume IDs liked by the user",
"type": "array",
"example": [
"EAR9JSFYP0",
"ABCDEFGHIJ"
],
"items": {
"type": "string",
"description": "Perfume ID"
}
},
"gender": {
"type": "string",
"description": "The user gender.",
"enum": [
"male",
"female",
"other"
]
},
"age": {
"type": "number",
"format": "int",
"nullable": true,
"example": 26,
"description": "The user age."
},
"restrict_to_store_id": {
"type": "string",
"nullable": true,
"example": "4242",
"description": "Restrict the recommendation to perfumes available in this store.\n"
},
"is_gift": {
"description": "Will this perfume be given to someone else as a gift?",
"type": "boolean",
"default": false
}
}
}
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| body | body | object | false | The user preferences |
| » perfumes_liked | body | [string] | true | List of perfume IDs liked by the user |
| » gender | body | string | true | The user gender. |
| » age | body | number(int)|null | false | The user age. |
| » restrict_to_store_id | body | string|null | false | Restrict the recommendation to perfumes available in this store. |
| » is_gift | body | boolean | false | Will this perfume be given to someone else as a gift? |
Enumerated Values
| Parameter | Value |
|---|---|
| » gender | male |
| » gender | female |
| » gender | other |
Example responses
200 Response
{
"type": "array",
"items": {
"type": "object",
"properties": {
"rank": {
"type": "number",
"example": 1
},
"score": {
"type": "number",
"format": "float",
"example": 0.92
},
"perfume": {
"type": "object",
"properties": {
"id": {
"type": "string",
"readOnly": true,
"description": "Sommelier du Parfum ID",
"example": "EAR9JSFYP0"
},
"name": {
"type": "string",
"description": "The perfume name",
"example": "Chance Eau de Toilette"
},
"brand_name": {
"type": "string",
"description": "The name of the perfume's brand",
"example": "Chanel"
},
"image_url": {
"type": "string",
"description": "URL to an image of the perfume",
"example": "https://s3.eu-central-1.amazonaws.com/fragrancebutler.me/images/EAR9JSFYP0.jpg"
}
}
}
}
}
}
Responses
| Status | Meaning | Description | Schema |
|---|---|---|---|
| 200 | OK | Engine has recommendations | Inline |
| 400 | Bad Request | Invalid preferences set | None |
| 401 | Unauthorized | Invalid authentication | None |
Response Schema
Status Code 200
| Name | Type | Required | Restrictions | Description |
|---|---|---|---|---|
| anonymous | [Recommendation] | false | none | none |
| » rank | number | false | none | none |
| » score | number(float) | false | none | none |
| » perfume | Perfume | false | none | none |
| »» id | string | false | read-only | Sommelier du Parfum ID |
| »» name | string | false | none | The perfume name |
| »» brand_name | string | false | none | The name of the perfume's brand |
| »» image_url | string | false | none | URL to an image of the perfume |
Autocomplete
get__autocomplete_perfumes
Code samples
# You can also use wget
curl -X GET https://test-api.sommelier.tech/v1.0//autocomplete/perfumes?name=type,string \
-H 'Accept: application/json' \
-H 'Authorization: Bearer {access-token}'
GET https://test-api.sommelier.tech/v1.0//autocomplete/perfumes?name=type,string HTTP/1.1
Host: test-api.sommelier.tech
Accept: application/json
var headers = {
'Accept':'application/json',
'Authorization':'Bearer {access-token}'
};
$.ajax({
url: 'https://test-api.sommelier.tech/v1.0//autocomplete/perfumes',
method: 'get',
data: '?name=type,string',
headers: headers,
success: function(data) {
console.log(JSON.stringify(data));
}
})
const request = require('node-fetch');
const headers = {
'Accept':'application/json',
'Authorization':'Bearer {access-token}'
};
fetch('https://test-api.sommelier.tech/v1.0//autocomplete/perfumes?name=type,string',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json',
'Authorization' => 'Bearer {access-token}'
}
result = RestClient.get 'https://test-api.sommelier.tech/v1.0//autocomplete/perfumes',
params: {
'name' => 'string'
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json',
'Authorization': 'Bearer {access-token}'
}
r = requests.get('https://test-api.sommelier.tech/v1.0//autocomplete/perfumes', params={
'name': {
"type": "string"
}
}, headers = headers)
print r.json()
URL obj = new URL("https://test-api.sommelier.tech/v1.0//autocomplete/perfumes?name=type,string");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer {access-token}"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("GET", "https://test-api.sommelier.tech/v1.0//autocomplete/perfumes", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
GET /autocomplete/perfumes
Return autocompletion results on perfume names.
Return autocompletion results for a input string of 3 characters minimum.
Perfumes will be matched if any of their words start with the input string.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| name | query | string | true | Part of the perfume name |
Example responses
200 Response
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"readOnly": true,
"description": "Sommelier du Parfum ID",
"example": "EAR9JSFYP0"
},
"name": {
"type": "string",
"description": "The perfume name",
"example": "Chance Eau de Toilette"
},
"brand_name": {
"type": "string",
"description": "The name of the perfume's brand",
"example": "Chanel"
},
"image_url": {
"type": "string",
"description": "URL to an image of the perfume",
"example": "https://s3.eu-central-1.amazonaws.com/fragrancebutler.me/images/EAR9JSFYP0.jpg"
}
}
}
}
Responses
| Status | Meaning | Description | Schema |
|---|---|---|---|
| 200 | OK | Autocompletion results returned | Inline |
| 400 | Bad Request | Invalid request | None |
| 401 | Unauthorized | Invalid authentication | None |
Response Schema
Status Code 200
| Name | Type | Required | Restrictions | Description |
|---|---|---|---|---|
| anonymous | [Perfume] | false | none | none |
| » id | string | false | read-only | Sommelier du Parfum ID |
| » name | string | false | none | The perfume name |
| » brand_name | string | false | none | The name of the perfume's brand |
| » image_url | string | false | none | URL to an image of the perfume |
get__autocomplete_notes
Code samples
# You can also use wget
curl -X GET https://test-api.sommelier.tech/v1.0//autocomplete/notes?name=type,string \
-H 'Accept: application/json' \
-H 'Authorization: Bearer {access-token}'
GET https://test-api.sommelier.tech/v1.0//autocomplete/notes?name=type,string HTTP/1.1
Host: test-api.sommelier.tech
Accept: application/json
var headers = {
'Accept':'application/json',
'Authorization':'Bearer {access-token}'
};
$.ajax({
url: 'https://test-api.sommelier.tech/v1.0//autocomplete/notes',
method: 'get',
data: '?name=type,string',
headers: headers,
success: function(data) {
console.log(JSON.stringify(data));
}
})
const request = require('node-fetch');
const headers = {
'Accept':'application/json',
'Authorization':'Bearer {access-token}'
};
fetch('https://test-api.sommelier.tech/v1.0//autocomplete/notes?name=type,string',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
require 'json'
headers = {
'Accept' => 'application/json',
'Authorization' => 'Bearer {access-token}'
}
result = RestClient.get 'https://test-api.sommelier.tech/v1.0//autocomplete/notes',
params: {
'name' => 'string'
}, headers: headers
p JSON.parse(result)
import requests
headers = {
'Accept': 'application/json',
'Authorization': 'Bearer {access-token}'
}
r = requests.get('https://test-api.sommelier.tech/v1.0//autocomplete/notes', params={
'name': {
"type": "string"
}
}, headers = headers)
print r.json()
URL obj = new URL("https://test-api.sommelier.tech/v1.0//autocomplete/notes?name=type,string");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
"bytes"
"net/http"
)
func main() {
headers := map[string][]string{
"Accept": []string{"application/json"},
"Authorization": []string{"Bearer {access-token}"},
}
data := bytes.NewBuffer([]byte{jsonReq})
req, err := http.NewRequest("GET", "https://test-api.sommelier.tech/v1.0//autocomplete/notes", data)
req.Header = headers
client := &http.Client{}
resp, err := client.Do(req)
// ...
}
GET /autocomplete/notes
Return autocompletion results on notes names.
Return autocompletion results for a input string of 3 characters minimum.
Notes will be matched if any of their words start with the input string.
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| name | query | string | true | Part of the note name |
Example responses
200 Response
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Sommelier du Parfum ID",
"example": "390"
},
"name": {
"type": "string",
"description": "The note name",
"example": "Rose"
},
"family": {
"type": "string",
"description": "The family name of the note",
"example": "Flowers"
}
}
}
}
Responses
| Status | Meaning | Description | Schema |
|---|---|---|---|
| 200 | OK | Autocompletion results returned | Inline |
| 400 | Bad Request | Invalid request | None |
| 401 | Unauthorized | Invalid authentication | None |
Response Schema
Status Code 200
| Name | Type | Required | Restrictions | Description |
|---|---|---|---|---|
| anonymous | [Note] | false | none | none |
| » id | string | false | none | Sommelier du Parfum ID |
| » name | string | false | none | The note name |
| » family | string | false | none | The family name of the note |
Schemas
Perfume
{
"type": "object",
"properties": {
"id": {
"type": "string",
"readOnly": true,
"description": "Sommelier du Parfum ID",
"example": "EAR9JSFYP0"
},
"name": {
"type": "string",
"description": "The perfume name",
"example": "Chance Eau de Toilette"
},
"brand_name": {
"type": "string",
"description": "The name of the perfume's brand",
"example": "Chanel"
},
"image_url": {
"type": "string",
"description": "URL to an image of the perfume",
"example": "https://s3.eu-central-1.amazonaws.com/fragrancebutler.me/images/EAR9JSFYP0.jpg"
}
}
}
Properties
| Name | Type | Required | Restrictions | Description |
|---|---|---|---|---|
| id | string | false | read-only | Sommelier du Parfum ID |
| name | string | false | none | The perfume name |
| brand_name | string | false | none | The name of the perfume's brand |
| image_url | string | false | none | URL to an image of the perfume |
Recommendation
{
"type": "object",
"properties": {
"rank": {
"type": "number",
"example": 1
},
"score": {
"type": "number",
"format": "float",
"example": 0.92
},
"perfume": {
"type": "object",
"properties": {
"id": {
"type": "string",
"readOnly": true,
"description": "Sommelier du Parfum ID",
"example": "EAR9JSFYP0"
},
"name": {
"type": "string",
"description": "The perfume name",
"example": "Chance Eau de Toilette"
},
"brand_name": {
"type": "string",
"description": "The name of the perfume's brand",
"example": "Chanel"
},
"image_url": {
"type": "string",
"description": "URL to an image of the perfume",
"example": "https://s3.eu-central-1.amazonaws.com/fragrancebutler.me/images/EAR9JSFYP0.jpg"
}
}
}
}
}
Properties
| Name | Type | Required | Restrictions | Description |
|---|---|---|---|---|
| rank | number | false | none | none |
| score | number(float) | false | none | none |
| perfume | Perfume | false | none | none |
Note
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Sommelier du Parfum ID",
"example": "390"
},
"name": {
"type": "string",
"description": "The note name",
"example": "Rose"
},
"family": {
"type": "string",
"description": "The family name of the note",
"example": "Flowers"
}
}
}
Properties
| Name | Type | Required | Restrictions | Description |
|---|---|---|---|---|
| id | string | false | none | Sommelier du Parfum ID |
| name | string | false | none | The note name |
| family | string | false | none | The family name of the note |