REST reference
Identify a cigar
Identify a cigar from one or more band images with the complete matching workflow.
POST
/
v1
/
matches
Identify a cigar
curl --request POST \
--url https://api.example.com/v1/matches \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--header 'x-boxpressd-key: <x-boxpressd-key>' \
--data '
{
"imageUrl": "<string>",
"imageUrls": [
"<string>"
],
"prompt": "<string>",
"suggestionLimit": 123,
"researchMode": "<string>",
"researchProfile": "<string>"
}
'import requests
url = "https://api.example.com/v1/matches"
payload = {
"imageUrl": "<string>",
"imageUrls": ["<string>"],
"prompt": "<string>",
"suggestionLimit": 123,
"researchMode": "<string>",
"researchProfile": "<string>"
}
headers = {
"x-boxpressd-key": "<x-boxpressd-key>",
"Idempotency-Key": "<idempotency-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-boxpressd-key': '<x-boxpressd-key>',
'Idempotency-Key': '<idempotency-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
imageUrl: '<string>',
imageUrls: ['<string>'],
prompt: '<string>',
suggestionLimit: 123,
researchMode: '<string>',
researchProfile: '<string>'
})
};
fetch('https://api.example.com/v1/matches', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v1/matches",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'imageUrl' => '<string>',
'imageUrls' => [
'<string>'
],
'prompt' => '<string>',
'suggestionLimit' => 123,
'researchMode' => '<string>',
'researchProfile' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>",
"x-boxpressd-key: <x-boxpressd-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v1/matches"
payload := strings.NewReader("{\n \"imageUrl\": \"<string>\",\n \"imageUrls\": [\n \"<string>\"\n ],\n \"prompt\": \"<string>\",\n \"suggestionLimit\": 123,\n \"researchMode\": \"<string>\",\n \"researchProfile\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-boxpressd-key", "<x-boxpressd-key>")
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v1/matches")
.header("x-boxpressd-key", "<x-boxpressd-key>")
.header("Idempotency-Key", "<idempotency-key>")
.header("Content-Type", "application/json")
.body("{\n \"imageUrl\": \"<string>\",\n \"imageUrls\": [\n \"<string>\"\n ],\n \"prompt\": \"<string>\",\n \"suggestionLimit\": 123,\n \"researchMode\": \"<string>\",\n \"researchProfile\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/matches")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-boxpressd-key"] = '<x-boxpressd-key>'
request["Idempotency-Key"] = '<idempotency-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"imageUrl\": \"<string>\",\n \"imageUrls\": [\n \"<string>\"\n ],\n \"prompt\": \"<string>\",\n \"suggestionLimit\": 123,\n \"researchMode\": \"<string>\",\n \"researchProfile\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyUse this route for an end-to-end band scan. It is an alias of
A successful response contains
The response header
POST /v1/ai/cigars/identify.
string
required
Your developer application key with the
api.ai entitlement.string
required
A unique key for this logical paid operation. Use letters, numbers,
., _, :, or - and at most 200 characters.string
A retrievable cigar or band image URL. Either
imageUrl or imageUrls is required unless force is true.string[]
Up to eight retrievable images of the same cigar or band.
string
Optional context of at most 2,000 characters, such as visible text or where the cigar was purchased.
integer
Number of suggestions to return, from 1 through 10.
string
default:"auto"
auto, open_world, or catalog_guided.string
quick or thorough.curl "https://api.boxpressd.com/v1/matches" \
--request POST \
--header "x-boxpressd-key: $BOXPRESSD_DEVELOPER_API_KEY" \
--header "Idempotency-Key: band-scan-7f52b86d" \
--header "Content-Type: application/json" \
--data "{\"imageUrl\":\"$CIGAR_BAND_IMAGE_URL\",\"researchMode\":\"auto\",\"suggestionLimit\":5}"
const response = await fetch("https://api.boxpressd.com/v1/matches", {
method: "POST",
headers: {
"x-boxpressd-key": process.env.BOXPRESSD_DEVELOPER_API_KEY,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
imageUrl: process.env.CIGAR_BAND_IMAGE_URL,
researchMode: "auto",
suggestionLimit: 5,
}),
});
const result = await response.json();
import axios from "axios";
const response = await axios.post(
"https://api.boxpressd.com/v1/matches",
{
imageUrl: process.env.CIGAR_BAND_IMAGE_URL,
researchMode: "auto",
suggestionLimit: 5,
},
{
headers: {
"x-boxpressd-key": process.env.BOXPRESSD_DEVELOPER_API_KEY,
"Idempotency-Key": crypto.randomUUID(),
},
},
);
status, processing metadata, and one or more of match, suggestions, or pendingSuggestions. Return a suggestions result to the user for confirmation instead of silently choosing the first candidate.
{
"status": "matched",
"match": {
"cigar_id": 1842,
"brand": "Drew Estate",
"name": "Liga Privada No. 9",
"confidence": 0.93,
"evidence": "combined"
},
"metadata": {
"source": "combined",
"image_count": 1,
"candidate_count": 4,
"gpt_fallback_used": true,
"decision_reason": "research_corroborated_stage_match"
}
}
x-boxpressd-ai-credits-remaining contains the spendable balance after settlement. See AI and cigar matching for staged workflows and billing errors.⌘I
Identify a cigar
curl --request POST \
--url https://api.example.com/v1/matches \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--header 'x-boxpressd-key: <x-boxpressd-key>' \
--data '
{
"imageUrl": "<string>",
"imageUrls": [
"<string>"
],
"prompt": "<string>",
"suggestionLimit": 123,
"researchMode": "<string>",
"researchProfile": "<string>"
}
'import requests
url = "https://api.example.com/v1/matches"
payload = {
"imageUrl": "<string>",
"imageUrls": ["<string>"],
"prompt": "<string>",
"suggestionLimit": 123,
"researchMode": "<string>",
"researchProfile": "<string>"
}
headers = {
"x-boxpressd-key": "<x-boxpressd-key>",
"Idempotency-Key": "<idempotency-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-boxpressd-key': '<x-boxpressd-key>',
'Idempotency-Key': '<idempotency-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
imageUrl: '<string>',
imageUrls: ['<string>'],
prompt: '<string>',
suggestionLimit: 123,
researchMode: '<string>',
researchProfile: '<string>'
})
};
fetch('https://api.example.com/v1/matches', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v1/matches",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'imageUrl' => '<string>',
'imageUrls' => [
'<string>'
],
'prompt' => '<string>',
'suggestionLimit' => 123,
'researchMode' => '<string>',
'researchProfile' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>",
"x-boxpressd-key: <x-boxpressd-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v1/matches"
payload := strings.NewReader("{\n \"imageUrl\": \"<string>\",\n \"imageUrls\": [\n \"<string>\"\n ],\n \"prompt\": \"<string>\",\n \"suggestionLimit\": 123,\n \"researchMode\": \"<string>\",\n \"researchProfile\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-boxpressd-key", "<x-boxpressd-key>")
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v1/matches")
.header("x-boxpressd-key", "<x-boxpressd-key>")
.header("Idempotency-Key", "<idempotency-key>")
.header("Content-Type", "application/json")
.body("{\n \"imageUrl\": \"<string>\",\n \"imageUrls\": [\n \"<string>\"\n ],\n \"prompt\": \"<string>\",\n \"suggestionLimit\": 123,\n \"researchMode\": \"<string>\",\n \"researchProfile\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v1/matches")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-boxpressd-key"] = '<x-boxpressd-key>'
request["Idempotency-Key"] = '<idempotency-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"imageUrl\": \"<string>\",\n \"imageUrls\": [\n \"<string>\"\n ],\n \"prompt\": \"<string>\",\n \"suggestionLimit\": 123,\n \"researchMode\": \"<string>\",\n \"researchProfile\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body