
Whisky & bourbon collection in AI: search the catalog, read and manage your shelf (OAuth).
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Add a bottle to your shelf, wishlist or Tried list (same as the app's Add Bottle form). Free accounts can hold 25 unopened/opened bottles; Pro is unlimited. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
Bottle name when it isn't in the catalog
Your tasting notes
unopened/opened count toward the free 25-bottle shelf; finished, wishlist and tried don't
Notes about this bottle (batch, gift, etc.)
Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token.
Your collection ids (list_my_collections)
Catalog path from search_catalog (preferred)
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Add a bottle to your shelf, wishlist or Tried list (same as the app's Add Bottle form). Free accounts can hold 25 unopened/opened bottles; Pro is unlimited. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| name | string | Bottle name when it isn't in the catalog |
| notes | string | Your tasting notes |
| proof | number | |
| rating | number | |
| status | string | unopened/opened count toward the free 25-bottle shelf; finished, wishlist and tried don't |
| distillery | string | |
| is_favorite | boolean | |
| bottle_notes | string | Notes about this bottle (batch, gift, etc.) |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
| collection_ids | array | Your collection ids (list_my_collections) |
| purchase_price | number | |
| purchased_from | string | |
| expression_path | string | Catalog path from search_catalog (preferred) |
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Bottle name when it isn't in the catalog"
},
"notes": {
"type": "string",
"description": "Your tasting notes"
},
"proof": {
"type": "number"
},
"rating": {
"type": "number",
"maximum": 5,
"minimum": 0,
"multipleOf": 0.25
},
"status": {
"enum": [
"unopened",
"opened",
"finished",
"wishlist",
"tried"
],
"type": "string",
"description": "unopened/opened count toward the free 25-bottle shelf; finished, wishlist and tried don't"
},
"distillery": {
"type": "string"
},
"is_favorite": {
"type": "boolean"
},
"bottle_notes": {
"type": "string",
"description": "Notes about this bottle (batch, gift, etc.)"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
},
"collection_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Your collection ids (list_my_collections)"
},
"purchase_price": {
"type": "number"
},
"purchased_from": {
"type": "string"
},
"expression_path": {
"type": "string",
"description": "Catalog path from search_catalog (preferred)"
}
},
"additionalProperties": false
}Add a bottle from a photo, like Add Bottle → photo in the app: the preview identifies it; after the user agrees, AI art is made from the photo (1K) and the bottle is added with it. Free: 5 AI art a day; Pro: unlimited. Two steps: repeat with confirm_token after the user agrees.
| Argument | Type | Description |
|---|---|---|
| name | string | Override the identified name |
| proof | number | |
| style | string | Art style. Free: Elements. Pro: Elements, Dark, Blended, Heritage, Oak, Cheers. |
| rating | number | |
| status | string | |
| imageData* | string | Base64 JPEG/PNG photo of the bottle (or a data: URL) |
| distillery | string | |
| confirm_token | string | Omit first: you get a preview (and what it costs). Repeat with identical arguments plus this token after the user agrees. |
{
"type": "object",
"required": [
"imageData"
],
"properties": {
"name": {
"type": "string",
"description": "Override the identified name"
},
"proof": {
"type": "number"
},
"style": {
"enum": [
"Elements",
"Dark",
"Blended",
"Heritage",
"Oak",
"Cheers"
],
"type": "string",
"default": "Elements",
"description": "Art style. Free: Elements. Pro: Elements, Dark, Blended, Heritage, Oak, Cheers."
},
"rating": {
"type": "number"
},
"status": {
"enum": [
"unopened",
"opened",
"finished",
"wishlist",
"tried"
],
"type": "string",
"default": "unopened"
},
"imageData": {
"type": "string",
"description": "Base64 JPEG/PNG photo of the bottle (or a data: URL)"
},
"distillery": {
"type": "string"
},
"confirm_token": {
"type": "string",
"description": "Omit first: you get a preview (and what it costs). Repeat with identical arguments plus this token after the user agrees."
}
},
"additionalProperties": false
}Add one of your bottles to one of your collections. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| bottle_id* | string | Id from list_my_bottles |
| collection_id* | string | Id from list_my_collections |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"bottle_id",
"collection_id"
],
"properties": {
"bottle_id": {
"type": "string",
"description": "Id from list_my_bottles"
},
"collection_id": {
"type": "string",
"description": "Id from list_my_collections"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Block someone: hides their posts and profile from your feed, Explore and Discover (doesn't unfollow, like the app). Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| userId | string | User id |
| username | string | Instadram handle (with or without @) |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"properties": {
"userId": {
"type": "string",
"description": "User id"
},
"username": {
"type": "string",
"description": "Instadram handle (with or without @)"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Check whether an @handle is valid and free before set_username (same rules and messages as Edit Profile).
| Argument | Type | Description |
|---|---|---|
| username* | string |
{
"type": "object",
"required": [
"username"
],
"properties": {
"username": {
"type": "string",
"maxLength": 64
}
},
"additionalProperties": false
}Create one of your collections. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| name* | string | |
| description | string | |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 80
},
"description": {
"type": "string"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Delete one of your collections. Its bottles stay on your shelf. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| collection_id* | string | Id from list_my_collections |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"collection_id"
],
"properties": {
"collection_id": {
"type": "string",
"description": "Id from list_my_collections"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Delete one of your own feed posts (id from list_my_activity). The bottle stays on your shelf. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| activity_id* | string | Id from list_my_activity |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"activity_id"
],
"properties": {
"activity_id": {
"type": "string",
"description": "Id from list_my_activity"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Discover people like the app's People list: everyone (empty query) or a name/handle match, ranked like the app, with badge and whether you follow them. Use follow_user to follow.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| query | string | |
| cursor | string | nextCursor from a previous page |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1
},
"query": {
"type": "string",
"maxLength": 100
},
"cursor": {
"type": "string",
"description": "nextCursor from a previous page"
}
},
"additionalProperties": false
}The Explore tab's bottle deck: recent public shelf bottles with photos from other collectors, one per expression, blocked and hidden accounts removed.
| Argument | Type | Description |
|---|---|---|
| limit | integer |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 30,
"maximum": 50,
"minimum": 1
}
},
"additionalProperties": false
}The Explore recipe feed: every drink, ordered by how few bottles you'd need to buy from your own shelf, then popularity. Paged with nextCursor.
| Argument | Type | Description |
|---|---|---|
| cursor | string | nextCursor from a previous page |
| pageSize | integer |
{
"type": "object",
"properties": {
"cursor": {
"type": "string",
"description": "nextCursor from a previous page"
},
"pageSize": {
"type": "integer",
"default": 20,
"maximum": 40,
"minimum": 1
}
},
"additionalProperties": false
}Export your whole collection as CSV (Pro, like Profile → Export Collection): the same columns and values as the app's file. Returns filename and csv text.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}AI community-review research for a bottle (fetchBottleReviews). Not a user tasting-note form. iOS may have this flagged off; the tool still works. Pass bottleName, or bottleId (own collection), or username/userId + bottleId to resolve the display name then research. Returns reviews_found, msrp, general_consensus, summary, overall_rating, reviewers. Read/research only — does not write Firestore.
| Argument | Type | Description |
|---|---|---|
| userId | string | Firebase uid of the target user |
| bottleId | string | Resolve display name from a collection doc, then research |
| username | string | Instadram handle (with or without @). Resolved via usernames/{handle}. |
| bottleName | string | Bottle display name to research |
{
"type": "object",
"properties": {
"userId": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Firebase uid of the target user"
},
"bottleId": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Resolve display name from a collection doc, then research"
},
"username": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Instadram handle (with or without @). Resolved via usernames/{handle}."
},
"bottleName": {
"type": "string",
"maxLength": 256,
"minLength": 1,
"description": "Bottle display name to research"
}
},
"additionalProperties": false
}Follow someone (username or userId from search_users). Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| userId | string | User id |
| username | string | Instadram handle (with or without @) |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"properties": {
"userId": {
"type": "string",
"description": "User id"
},
"username": {
"type": "string",
"description": "Instadram handle (with or without @)"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Get one public catalog expression by id, or by path distilleries/{id}/brands/{id}/expressions/{id}.
| Argument | Type | Description |
|---|---|---|
| expressionId* | string | Expression document id or nested catalog path |
{
"type": "object",
"required": [
"expressionId"
],
"properties": {
"expressionId": {
"type": "string",
"maxLength": 256,
"minLength": 1,
"description": "Expression document id or nested catalog path"
}
},
"additionalProperties": false
}The Home feed as the app shows it: recent pours, adds and ratings from everyone (scope global, the app default) or only people you follow plus you (scope following). Blocked and hidden accounts are removed.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| scope | string | |
| cursor | string | nextCursor from a previous page |
| offset | integer |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1
},
"scope": {
"enum": [
"global",
"following"
],
"type": "string",
"default": "global"
},
"cursor": {
"type": "string",
"description": "nextCursor from a previous page"
},
"offset": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
}Get one bottle from the signed-in user's collection by id. 404 if missing or not theirs.
| Argument | Type | Description |
|---|---|---|
| bottleId* | string | Bottle document id in the caller's collection |
{
"type": "object",
"required": [
"bottleId"
],
"properties": {
"bottleId": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Bottle document id in the caller's collection"
}
},
"additionalProperties": false
}Value of the signed-in user's active shelf (opened + unopened) in USD, the same number as the app's Stats. paid: purchase price, or MSRP when no price was entered (msrpCount says how many used MSRP). msrp: every bottle at MSRP. excludedCount bottles have no usable price. totalCents is exact; total is dollars. Always scoped to the token uid.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Get one public profile by username or userId. Resolves handles via usernames/{handle}. Public fields only — no email, stripeCustomerId, or billing.
| Argument | Type | Description |
|---|---|---|
| userId | string | Firebase uid of the target user |
| username | string | Instadram handle (with or without @). Resolved via usernames/{handle}. |
{
"type": "object",
"properties": {
"userId": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Firebase uid of the target user"
},
"username": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Instadram handle (with or without @). Resolved via usernames/{handle}."
}
},
"additionalProperties": false
}Get one bottle from another user's public collection. Requires username or userId plus bottleId. 404 if the user or bottle is missing.
| Argument | Type | Description |
|---|---|---|
| userId | string | Firebase uid of the target user |
| bottleId* | string | Bottle document id in the target user's collection |
| username | string | Instadram handle (with or without @). Resolved via usernames/{handle}. |
{
"type": "object",
"required": [
"bottleId"
],
"properties": {
"userId": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Firebase uid of the target user"
},
"bottleId": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Bottle document id in the target user's collection"
},
"username": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Instadram handle (with or without @). Resolved via usernames/{handle}."
}
},
"additionalProperties": false
}List the signed-in user's own pours/activity. Never returns other users' activity.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Page size (max 50) |
| cursor | string | Opaque pagination cursor from a previous response (numeric offset) |
| offset | integer | Number of items to skip |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1,
"description": "Page size (max 50)"
},
"cursor": {
"type": "string",
"description": "Opaque pagination cursor from a previous response (numeric offset)"
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Number of items to skip"
}
},
"additionalProperties": false
}List bottles in the signed-in user's collection. Filters: status (unopened|opened|consumed|excluded|wishlist|active|tried) and optional text query. Always scoped to the token uid — a userId argument is ignored.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Page size (max 50) |
| query | string | Filter by display name, distillery, or notes |
| cursor | string | Opaque pagination cursor from a previous response (numeric offset) |
| offset | integer | Number of items to skip |
| status | string | Bottle status or shelf group (active / wishlist / tried) |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1,
"description": "Page size (max 50)"
},
"query": {
"type": "string",
"maxLength": 100,
"minLength": 1,
"description": "Filter by display name, distillery, or notes"
},
"cursor": {
"type": "string",
"description": "Opaque pagination cursor from a previous response (numeric offset)"
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Number of items to skip"
},
"status": {
"enum": [
"unopened",
"opened",
"consumed",
"excluded",
"wishlist",
"active",
"tried"
],
"type": "string",
"description": "Bottle status or shelf group (active / wishlist / tried)"
}
},
"additionalProperties": false
}List the signed-in user's shelf groups / collections.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Page size (max 50) |
| cursor | string | Opaque pagination cursor from a previous response (numeric offset) |
| offset | integer | Number of items to skip |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1,
"description": "Page size (max 50)"
},
"cursor": {
"type": "string",
"description": "Opaque pagination cursor from a previous response (numeric offset)"
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Number of items to skip"
}
},
"additionalProperties": false
}List another user's pours/activity (authenticated feed read). Requires username or userId. Newest first. Same paging caps as list_my_activity.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Page size (max 50) |
| cursor | string | Opaque pagination cursor from a previous response (numeric offset) |
| offset | integer | Number of items to skip |
| userId | string | Firebase uid of the target user |
| username | string | Instadram handle (with or without @). Resolved via usernames/{handle}. |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1,
"description": "Page size (max 50)"
},
"cursor": {
"type": "string",
"description": "Opaque pagination cursor from a previous response (numeric offset)"
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Number of items to skip"
},
"userId": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Firebase uid of the target user"
},
"username": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Instadram handle (with or without @). Resolved via usernames/{handle}."
}
},
"additionalProperties": false
}List bottles on another user's public shelf. Requires username or userId. Same status/query/paging as list_my_bottles. 404 if the user is missing; empty list if they have no bottles.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Page size (max 50) |
| query | string | Filter by display name, distillery, or notes |
| cursor | string | Opaque pagination cursor from a previous response (numeric offset) |
| offset | integer | Number of items to skip |
| status | string | Bottle status or shelf group (active / wishlist / tried) |
| userId | string | Firebase uid of the target user |
| username | string | Instadram handle (with or without @). Resolved via usernames/{handle}. |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1,
"description": "Page size (max 50)"
},
"query": {
"type": "string",
"maxLength": 100,
"minLength": 1,
"description": "Filter by display name, distillery, or notes"
},
"cursor": {
"type": "string",
"description": "Opaque pagination cursor from a previous response (numeric offset)"
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Number of items to skip"
},
"status": {
"enum": [
"unopened",
"opened",
"consumed",
"excluded",
"wishlist",
"active",
"tried"
],
"type": "string",
"description": "Bottle status or shelf group (active / wishlist / tried)"
},
"userId": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Firebase uid of the target user"
},
"username": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Instadram handle (with or without @). Resolved via usernames/{handle}."
}
},
"additionalProperties": false
}List another user's public shelf groups. Requires username or userId.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Page size (max 50) |
| cursor | string | Opaque pagination cursor from a previous response (numeric offset) |
| offset | integer | Number of items to skip |
| userId | string | Firebase uid of the target user |
| username | string | Instadram handle (with or without @). Resolved via usernames/{handle}. |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1,
"description": "Page size (max 50)"
},
"cursor": {
"type": "string",
"description": "Opaque pagination cursor from a previous response (numeric offset)"
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Number of items to skip"
},
"userId": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Firebase uid of the target user"
},
"username": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Instadram handle (with or without @). Resolved via usernames/{handle}."
}
},
"additionalProperties": false
}Log that you're drinking one of your bottles (posts to your followers' feed, like the app's Pour). Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| bottle_id* | string | Id from list_my_bottles |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"bottle_id"
],
"properties": {
"bottle_id": {
"type": "string",
"description": "Id from list_my_bottles"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Add-bottle AI identify (analyzeBourbonImage). Photo (imageData) or text (query). Returns distillery, location, spirit.brand + expressions (name, proof, msrp, tasting_notes, etc.), success, confidence. Does not write a bottle or set expressionRef. Never generates art (transformImage is not used).
| Argument | Type | Description |
|---|---|---|
| query | string | Bottle name when no photo is available |
| imageData | string | Base64 bottle photo, same as analyzeBourbonImage |
{
"type": "object",
"properties": {
"query": {
"type": "string",
"maxLength": 256,
"minLength": 1,
"description": "Bottle name when no photo is available"
},
"imageData": {
"type": "string",
"minLength": 1,
"description": "Base64 bottle photo, same as analyzeBourbonImage"
}
},
"additionalProperties": false
}Rate one of your bottles 0-5 in steps of 0.25 (0 clears). Posts a 'rated' update like the app. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| rating* | number | |
| bottle_id* | string | Id from list_my_bottles |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"bottle_id",
"rating"
],
"properties": {
"rating": {
"type": "number",
"maximum": 5,
"minimum": 0,
"multipleOf": 0.25
},
"bottle_id": {
"type": "string",
"description": "Id from list_my_bottles"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Make new AI art for one of your bottles from its stored photo (or a new photo), like Think harder → Only regenerate the art. Uses 1 AI art credit (free 5/day, Pro unlimited). Two steps.
| Argument | Type | Description |
|---|---|---|
| style | string | Art style. Free: Elements. Pro: Elements, Dark, Blended, Heritage, Oak, Cheers. |
| bottle_id* | string | |
| imageData | string | Base64 JPEG/PNG photo of the bottle (or a data: URL) |
| confirm_token | string | Omit first: you get a preview (and what it costs). Repeat with identical arguments plus this token after the user agrees. |
{
"type": "object",
"required": [
"bottle_id"
],
"properties": {
"style": {
"enum": [
"Elements",
"Dark",
"Blended",
"Heritage",
"Oak",
"Cheers"
],
"type": "string",
"default": "Elements",
"description": "Art style. Free: Elements. Pro: Elements, Dark, Blended, Heritage, Oak, Cheers."
},
"bottle_id": {
"type": "string"
},
"imageData": {
"type": "string",
"description": "Base64 JPEG/PNG photo of the bottle (or a data: URL)"
},
"confirm_token": {
"type": "string",
"description": "Omit first: you get a preview (and what it costs). Repeat with identical arguments plus this token after the user agrees."
}
},
"additionalProperties": false
}Think harder about one of your bottles: identify it again from its photo and research fresh reviews. Reviews are saved when found; pass update_identity to also replace the name, distillery and proof. Two steps.
| Argument | Type | Description |
|---|---|---|
| bottle_id* | string | |
| imageData | string | Base64 JPEG/PNG photo of the bottle (or a data: URL) |
| confirm_token | string | Omit first: you get a preview (and what it costs). Repeat with identical arguments plus this token after the user agrees. |
| update_identity | boolean |
{
"type": "object",
"required": [
"bottle_id"
],
"properties": {
"bottle_id": {
"type": "string"
},
"imageData": {
"type": "string",
"description": "Base64 JPEG/PNG photo of the bottle (or a data: URL)"
},
"confirm_token": {
"type": "string",
"description": "Omit first: you get a preview (and what it costs). Repeat with identical arguments plus this token after the user agrees."
},
"update_identity": {
"type": "boolean",
"default": false
}
},
"additionalProperties": false
}Permanently delete one of your bottles. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| bottle_id* | string | Id from list_my_bottles |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"bottle_id"
],
"properties": {
"bottle_id": {
"type": "string",
"description": "Id from list_my_bottles"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Take one of your bottles out of one of your collections (the bottle stays on your shelf). Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| bottle_id* | string | Id from list_my_bottles |
| collection_id* | string | Id from list_my_collections |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"bottle_id",
"collection_id"
],
"properties": {
"bottle_id": {
"type": "string",
"description": "Id from list_my_bottles"
},
"collection_id": {
"type": "string",
"description": "Id from list_my_collections"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Rename one of your collections (and optionally change its description). Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| name* | string | |
| description | string | |
| collection_id* | string | Id from list_my_collections |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"collection_id",
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 80
},
"description": {
"type": "string"
},
"collection_id": {
"type": "string",
"description": "Id from list_my_collections"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Search the public bottle catalog (expressions and distilleries). Does not return other users' collections.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Page size (max 50) |
| query* | string | |
| cursor | string | Opaque pagination cursor from a previous response (numeric offset) |
| offset | integer | Number of items to skip |
{
"type": "object",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1,
"description": "Page size (max 50)"
},
"query": {
"type": "string",
"maxLength": 100,
"minLength": 1
},
"cursor": {
"type": "string",
"description": "Opaque pagination cursor from a previous response (numeric offset)"
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Number of items to skip"
}
},
"additionalProperties": false
}Cocktails to make with a bottle, like the app's recipe rail on a bottle page. Pass the bottle's name (plus spiritType, category, proof when known). Results note how many of the main liquors you already own. For browsing all drinks use explore_recipes.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| proof | number | |
| category | string | |
| bottleName* | string | Bottle display name |
| spiritType | string | e.g. bourbon, gin |
{
"type": "object",
"required": [
"bottleName"
],
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1
},
"proof": {
"type": "number"
},
"category": {
"type": "string",
"maxLength": 60
},
"bottleName": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Bottle display name"
},
"spiritType": {
"type": "string",
"maxLength": 60,
"description": "e.g. bourbon, gin"
}
},
"additionalProperties": false
}Search bottles like the app's Search tab: other collectors' shelf bottles (with owner username and display name) plus public catalog bottles, ranked like the app. Paged with nextCursor/hasMore/total.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| query* | string | |
| cursor | string | nextCursor from a previous page |
| offset | integer |
{
"type": "object",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1
},
"query": {
"type": "string",
"maxLength": 100,
"minLength": 2
},
"cursor": {
"type": "string",
"description": "nextCursor from a previous page"
},
"offset": {
"type": "integer",
"minimum": 0
}
},
"additionalProperties": false
}Search public Instadram profiles by exact username (usernames/{handle} or users.username) then displayName prefix. Returns uid, username, displayName, photoURL. Never email or billing fields.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Page size (max 50) |
| query* | string | Username or display-name prefix |
| cursor | string | Opaque pagination cursor from a previous response (numeric offset) |
| offset | integer | Number of items to skip |
{
"type": "object",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 50,
"minimum": 1,
"description": "Page size (max 50)"
},
"query": {
"type": "string",
"maxLength": 100,
"minLength": 1,
"description": "Username or display-name prefix"
},
"cursor": {
"type": "string",
"description": "Opaque pagination cursor from a previous response (numeric offset)"
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Number of items to skip"
}
},
"additionalProperties": false
}Send a bug report, feature idea or other feedback to the Instadram team as you (same as Profile → Send Feedback). 10–5000 characters. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| kind* | string | |
| message* | string | |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"kind",
"message"
],
"properties": {
"kind": {
"enum": [
"bug",
"enhancement",
"other"
],
"type": "string"
},
"message": {
"type": "string",
"maxLength": 5000,
"minLength": 10
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Move a bottle between unopened, opened, finished, wishlist and tried. Moving into unopened/opened re-checks the free 25-bottle limit. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| status* | string | unopened/opened count toward the free 25-bottle shelf; finished, wishlist and tried don't |
| bottle_id* | string | Id from list_my_bottles |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"bottle_id",
"status"
],
"properties": {
"status": {
"enum": [
"unopened",
"opened",
"finished",
"wishlist",
"tried"
],
"type": "string",
"description": "unopened/opened count toward the free 25-bottle shelf; finished, wishlist and tried don't"
},
"bottle_id": {
"type": "string",
"description": "Id from list_my_bottles"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Change your @handle (3–20 characters: lowercase letters, numbers, underscore). Your old handle is released. Use check_username first. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| username* | string | New handle, with or without @ |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"username"
],
"properties": {
"username": {
"type": "string",
"description": "New handle, with or without @"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Unblock every user you've blocked (same as Profile → Unblock All Users). Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"properties": {
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Stop following someone. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| userId | string | User id |
| username | string | Instadram handle (with or without @) |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"properties": {
"userId": {
"type": "string",
"description": "User id"
},
"username": {
"type": "string",
"description": "Instadram handle (with or without @)"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Edit your bottle: notes, price, store, custom name/distillery/proof, batch, barrel details, favorite. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| fields* | object | |
| bottle_id* | string | Id from list_my_bottles |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"bottle_id",
"fields"
],
"properties": {
"fields": {
"type": "object",
"properties": {
"notes": {
"type": [
"string",
"null"
]
},
"custom_name": {
"type": [
"string",
"null"
]
},
"is_favorite": {
"type": "boolean"
},
"batch_number": {
"type": [
"string",
"null"
]
},
"bottle_notes": {
"type": [
"string",
"null"
]
},
"custom_proof": {
"type": [
"number",
"null"
]
},
"barrel_number": {
"type": [
"string",
"null"
]
},
"purchase_price": {
"type": [
"number",
"null"
]
},
"purchased_from": {
"type": [
"string",
"null"
]
},
"barrel_mashbill": {
"type": [
"string",
"null"
]
},
"store_pick_name": {
"type": [
"string",
"null"
]
},
"barrel_warehouse": {
"type": [
"string",
"null"
]
},
"barrel_floor_rick": {
"type": [
"string",
"null"
]
},
"custom_distillery": {
"type": [
"string",
"null"
]
},
"barrel_age_at_bottling": {
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
},
"bottle_id": {
"type": "string",
"description": "Id from list_my_bottles"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}Edit your profile like Edit Profile in the app: displayName, bio, location, website, instagram, twitter, facebook, tiktok. Only fields you pass change; an empty string clears an optional field. Photos and handle aren't changed here (see set_username). Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| bio | string | Bio |
| tiktok | string | tiktok; empty string clears it |
| string | twitter; empty string clears it | |
| website | string | website; empty string clears it |
| string | facebook; empty string clears it | |
| location | string | location; empty string clears it |
| string | instagram; empty string clears it | |
| displayName | string | Display name |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
Return the signed-in user's public profile (uid, username, display name) plus pro (paid or gifted Instadram Pro). Uses the Bearer token uid only. Available to free users.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Put a bottle on your wishlist: a new one (expression_path or name), or move an existing bottle_id there. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| name | string | Bottle name when it isn't in the catalog |
| bottle_id | string | Id from list_my_bottles |
| distillery | string | |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
| expression_path | string | Catalog path from search_catalog (preferred) |
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Bottle name when it isn't in the catalog"
},
"bottle_id": {
"type": "string",
"description": "Id from list_my_bottles"
},
"distillery": {
"type": "string"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
},
"expression_path": {
"type": "string",
"description": "Catalog path from search_catalog (preferred)"
}
},
"additionalProperties": false
}Delete a bottle from your wishlist. Two steps: the first call only previews and returns confirm_token; show the preview to the user and repeat the call with confirm_token only after they agree.
| Argument | Type | Description |
|---|---|---|
| bottle_id* | string | Id from list_my_bottles |
| confirm_token | string | Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token. |
{
"type": "object",
"required": [
"bottle_id"
],
"properties": {
"bottle_id": {
"type": "string",
"description": "Id from list_my_bottles"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}{
"type": "object",
"properties": {
"bio": {
"type": "string",
"maxLength": 500,
"description": "Bio"
},
"tiktok": {
"type": "string",
"maxLength": 200,
"description": "tiktok; empty string clears it"
},
"twitter": {
"type": "string",
"maxLength": 200,
"description": "twitter; empty string clears it"
},
"website": {
"type": "string",
"maxLength": 200,
"description": "website; empty string clears it"
},
"facebook": {
"type": "string",
"maxLength": 200,
"description": "facebook; empty string clears it"
},
"location": {
"type": "string",
"maxLength": 200,
"description": "location; empty string clears it"
},
"instagram": {
"type": "string",
"maxLength": 200,
"description": "instagram; empty string clears it"
},
"displayName": {
"type": "string",
"maxLength": 200,
"description": "Display name"
},
"confirm_token": {
"type": "string",
"description": "Omit on the first call to get a preview. After the user agrees, call again with identical arguments plus this token."
}
},
"additionalProperties": false
}