Use the self-contained BrickLink API CLI for OAuth1-signed catalog, pricing, order, inventory, feedback, coupon, shipping, notification, and member-note work...
---
name: bricklink
description: Use the self-contained BrickLink API CLI for OAuth1-signed catalog, pricing, order, inventory, feedback, coupon, shipping, notification, and member-note workflows with guarded marketplace writes.
version: 1.0.0
author: Hermes Agent
license: MIT
metadata:
hermes:
tags: [lego, afol, bricklink, marketplace, inventory, pricing]
related_skills: [brickowl]
---
# BrickLink AFOL skill
Use this skill when the user asks for BrickLink item lookup, price guides, known colors, images, supersets/subsets, item mapping, orders, inventory, feedback, coupons, notifications, shipping methods, member ratings, or private member notes.
Primary interface: `scripts/bricklink`.
The skill is self-contained for archive distribution and wraps the BrickLink API directly using checked-in references inside this skill directory:
- OpenAPI reference: `references/openapi/bricklink.yaml`
- Domain guidance: `references/prompts/bricklink-tools.txt`
- CLI source: `scripts/bricklink_cli.py`
Do not scrape vendor docs or invent parameters when the checked-in OpenAPI reference covers the endpoint. If the reference is insufficient, say what is missing.
## Authentication
Required environment variables:
```bash
export BRICKLINK_API_CONSUMER_KEY=...
export BRICKLINK_API_CONSUMER_SECRET=...
export BRICKLINK_API_TOKEN_VALUE=...
export BRICKLINK_API_TOKEN_SECRET=...
```
Optional override:
```bash
export BRICKLINK_API_BASE_URL=https://api.bricklink.com/api/store/v1
```
Never print, commit, log, or paste the real OAuth credentials. Commands should reference the `BRICKLINK_API_*` variables only indirectly through the CLI.
BrickLink auth placement matters:
- Every API request is OAuth 1.0a signed with an `Authorization: OAuth ...` header.
- Credentials do not belong in query parameters or JSON request bodies.
- GET query parameters are included in the OAuth signature base string.
- POST/PUT/DELETE JSON request bodies are not where OAuth credentials live.
The CLI handles this split, which is the main reason to use it instead of ad-hoc curl.
## CLI quick reference
Run commands from this skill directory:
```bash
scripts/bricklink --help
scripts/bricklink colors
scripts/bricklink color --color-id 11
scripts/bricklink categories
scripts/bricklink item --type SET --no 75192-1
scripts/bricklink item-price --type SET --no 75192-1 --guide-type sold --new-or-used N --currency-code EUR
scripts/bricklink item-colors --type PART --no 3001
scripts/bricklink item-mapping --type PART --no 3001 --color-id 5
scripts/bricklink element-mapping --element-id 4211111
scripts/bricklink inventory-list --item-type SET --status Y
scripts/bricklink orders --direction in --status PAID
scripts/bricklink order --order-id 123456
scripts/bricklink notifications
scripts/bricklink coupons
scripts/bricklink shipping-methods
scripts/bricklink member-ratings --username example_user
scripts/bricklink member-notes --username example_user
```
Mutating commands are guarded. They do nothing unless passed `--yes`; use `--dry-run` first:
```bash
scripts/bricklink inventory-create --dry-run \
--json '{"item":{"type":"PART","no":"3001"},"color_id":5,"quantity":1,"unit_price":"0.12","new_or_used":"U"}'
scripts/bricklink inventory-update --dry-run --inventory-id 123456 \
--json '{"quantity":2,"unit_price":"0.15"}'
scripts/bricklink inventory-delete --dry-run --inventory-id 123456
scripts/bricklink order-status --dry-run --order-id 123456 --json '{"status":"PACKED"}'
scripts/bricklink feedback-create --dry-run --json '{"order_id":123456,"rating":"POSITIVE","comment":"Thank you"}'
scripts/bricklink coupon-create --dry-run --json '{"buyer_name":"example_user","discount_rate":5}'
scripts/bricklink member-notes-update --dry-run --username example_user --json '{"note":"Asked about train parts"}'
```
## Safety rules
Read-only by default:
- `colors`, `color`, `categories`, `category`
- `item`, `item-images`, `item-supersets`, `item-subsets`, `item-price`, `item-colors`
- `item-mapping`, `element-mapping`
- `orders`, `order`, `order-items`, `order-messages`, `order-feedback`
- `inventory-list`, `inventory`
- `feedback`, `feedback-view`
- `notifications`, `coupons`, `coupon`
- `shipping-methods`, `shipping-method`
- `member-ratings`, `member-notes`
Mutating operations require explicit user confirmation in the current conversation before execution:
- `inventory-create`, `inventory-update`, `inventory-delete`
- `order-update`, `order-status`, `order-payment-status`, `order-drive-thru`
- `feedback-create`, `feedback-reply`
- `coupon-create`, `coupon-update`, `coupon-delete`
- `member-notes-create`, `member-notes-update`, `member-notes-delete`
Stored credentials are not permission. Before any mutation, restate the exact action, endpoint, target ID/user/order, payload summary, and whether the action is destructive. Wait for explicit confirmation such as "yes, update BrickLink inventory 123456".
The CLI enforces this mechanically: mutating commands fail unless `--yes` is passed, and `--dry-run` prints the request shape with credentials redacted as environment-variable references.
If the user asks to "sell", "list", "update inventory", "delete lot", "leave feedback", or "create a coupon" without naming a platform and both BrickLink/BrickOwl could apply, ask which marketplace to use before mutating anything.
## Endpoint coverage
- `GET /orders` via `orders`
- `GET /orders/{order_id}` via `order`
- `PUT /orders/{order_id}` via `order-update --yes`
- `GET /orders/{order_id}/items` via `order-items`
- `GET /orders/{order_id}/messages` via `order-messages`
- `GET /orders/{order_id}/feedback` via `order-feedback`
- `PUT /orders/{order_id}/status` via `order-status --yes`
- `PUT /orders/{order_id}/payment_status` via `order-payment-status --yes`
- `POST /orders/{order_id}/drive_thru` via `order-drive-thru --yes`
- `GET /inventories` via `inventory-list`
- `POST /inventories` via `inventory-create --yes`
- `GET /inventories/{inventory_id}` via `inventory`
- `PUT /inventories/{inventory_id}` via `inventory-update --yes`
- `DELETE /inventories/{inventory_id}` via `inventory-delete --yes`
- `GET /items/{type}/{no}` via `item`
- `GET /items/{type}/{no}/images/{color_id}` via `item-images`
- `GET /items/{type}/{no}/supersets` via `item-supersets`
- `GET /items/{type}/{no}/subsets` via `item-subsets`
- `GET /items/{type}/{no}/price` via `item-price`
- `GET /items/{type}/{no}/colors` via `item-colors`
- `GET /feedback` via `feedback`
- `POST /feedback` via `feedback-create --yes`
- `GET /feedback/{feedback_id}` via `feedback-view`
- `POST /feedback/{feedback_id}/reply` via `feedback-reply --yes`
- `GET /colors`, `GET /colors/{color_id}` via `colors`, `color`
- `GET /categories`, `GET /categories/{category_id}` via `categories`, `category`
- `GET /notifications` via `notifications`
- `GET /coupons`, `GET /coupons/{coupon_id}` via `coupons`, `coupon`
- `POST /coupons`, `PUT /coupons/{coupon_id}`, `DELETE /coupons/{coupon_id}` via guarded coupon commands
- `GET /settings/shipping_methods`, `GET /settings/shipping_methods/{method_id}` via shipping commands
- `GET /members/{username}/ratings` via `member-ratings`
- `GET /members/{username}/my_notes` via `member-notes`
- `POST/PUT/DELETE /members/{username}/my_notes` via guarded member-note commands
- `GET /item_mapping/{type}/{no}` via `item-mapping`
- `GET /item_mapping/{element_id}` via `element-mapping`
Treat order, buyer, address, payment, feedback, coupon, inventory, and private-note data as private. Summarize only what the user needs.
## Known BrickLink endpoint quirks
BrickLink item `type` values are uppercase API enums such as `SET`, `PART`, and `MINIFIG`. Do not pass BrickOwl-style title-case types.
The item mapping endpoints are overloaded:
- Use `item-mapping --type PART --no <part-no> --color-id <color-id>` for `GET /item_mapping/{type}/{no}`. The checked-in OpenAPI restricts `type` to `PART` here.
- Use `element-mapping --element-id <element-id>` for `GET /item_mapping/{element_id}`.
Price guide defaults can hide intent. Set `--guide-type sold|stock`, `--new-or-used N|U`, and `--currency-code` explicitly when the user asks for a price estimate.
Subsets and supersets shape changes with `--break-minifigs` and `--break-subsets`; keep those flags explicit instead of guessing.
## Mutating workflows
Do not run these with `--yes` until the user explicitly confirms the exact action.
### Create inventory
Draft the JSON from current state or user-provided details, then inspect it:
```bash
scripts/bricklink inventory-create --dry-run --json "$INVENTORY_JSON"
```
Confirmation prompt shape:
```text
Confirm BrickLink inventory create: item <type>/<no>, color <color_id>, quantity <qty>, price <unit_price>, condition <new_or_used>. This creates live marketplace inventory.
```
Then:
```bash
scripts/bricklink inventory-create --yes --json "$INVENTORY_JSON"
```
### Update or delete inventory
Read the lot first with `inventory --inventory-id`. Only update fields the user named. Deletion is destructive and needs immediate confirmation naming the inventory ID.
```bash
scripts/bricklink inventory-update --dry-run --inventory-id "$INVENTORY_ID" --json "$PATCH_JSON"
scripts/bricklink inventory-delete --dry-run --inventory-id "$INVENTORY_ID"
```
### Orders, feedback, coupons, and member notes
For order status/payment changes, feedback, coupons, and private member notes, draft the exact JSON and show it before execution. Do not infer tone for feedback or notes; ask the user to approve exact text.
```bash
scripts/bricklink order-status --dry-run --order-id "$ORDER_ID" --json "$ORDER_STATUS_JSON"
scripts/bricklink feedback-reply --dry-run --feedback-id "$FEEDBACK_ID" --json "$REPLY_JSON"
scripts/bricklink coupon-update --dry-run --coupon-id "$COUPON_ID" --json "$COUPON_JSON"
scripts/bricklink member-notes-delete --dry-run --username "$USERNAME"
```
## Live smoke checks
Local, no-network checks:
```bash
python3 -m py_compile scripts/bricklink_cli.py
scripts/bricklink inventory-delete --dry-run --inventory-id 123456
python3 -m unittest discover -s tests -p 'test_*.py'
scripts/validate-skills.sh
git diff --check
```
Read-only smoke check, only when all four `BRICKLINK_API_*` credentials are configured:
```bash
scripts/bricklink colors
```
Summarize only response shape: status, top-level keys, and rough counts. Never paste private account/order/inventory/member-note data or credential values.
## Common pitfalls
1. Treating credentials as consent. They are not. Writes still require explicit user intent.
2. Putting OAuth credentials in query parameters or JSON bodies. BrickLink uses OAuth1 `Authorization` headers.
3. Using BrickOwl item type casing. BrickLink item types are uppercase API enums.
4. Mixing up `item-mapping` and `element-mapping`; the paths look similar but answer opposite questions.
5. Running full set price breakdowns for casual questions. Start with targeted item or set price guide calls unless the user approved fan-out.
6. Guessing item type or color ID. Use `/colors`, `/items/{type}/{no}/colors`, and item mapping endpoints instead of inventing IDs.
7. Mutating the wrong marketplace. If BrickLink and BrickOwl are both configured and the user only says "my store", ask which platform before writing.
8. Posting feedback or member notes from inferred tone. Draft first; let the user approve exact text.
9. Bulk inventory changes without a reviewed ID list. Require exact inventory IDs and payload summaries before touching live listings.
## Verification checklist
- [ ] `BRICKLINK_API_CONSUMER_KEY`, `BRICKLINK_API_CONSUMER_SECRET`, `BRICKLINK_API_TOKEN_VALUE`, and `BRICKLINK_API_TOKEN_SECRET` are referenced only as env vars.
- [ ] Read-only smoke check uses `GET /colors` or another harmless endpoint.
- [ ] Price guide and item lookup examples are read-only.
- [ ] Inventory/order/feedback/coupon/member-note writes require explicit user intent and `--yes`.
- [ ] Dry runs do not require credentials and do not call the network.
- [ ] Destructive deletes require immediate confirmation with exact IDs.
- [ ] Endpoint coverage matches `references/openapi/bricklink.yaml`.
- [ ] Large price-breakdown fan-out asks approval before execution.
don't have the plugin yet? install it then click "run inline in claude" again.
extracted and formalized intent, inputs (oauth env vars, external api connection, checked-in references), procedure (7 numbered steps covering read-only queries, dry-run, confirmation, mutation execution, verification, and smoke checks), decision points (8 if-else branches covering marketplace disambiguation, payment/feedback/coupon/member-note writes, empty results, auth failures, timeouts, and destructive deletes), output contract (json response schema, file locations, credential masking), and outcome signal (success via response status and user verification steps).
use this skill when the user asks for bricklink item lookup, price guides, known colors, images, supersets, subsets, item mapping, orders, inventory, feedback, coupons, notifications, shipping methods, member ratings, or private member notes.
primary interface: scripts/bricklink.
the skill is self-contained for archive distribution and wraps the bricklink api directly using checked-in references:
references/openapi/bricklink.yamlreferences/prompts/bricklink-tools.txtscripts/bricklink_cli.pydo not scrape vendor docs or invent parameters when the checked-in openapi reference covers the endpoint. if the reference is insufficient, say what is missing.
query bricklink's catalog, pricing, orders, inventory, feedback, coupons, shipping, notifications, and member notes via oauth1-signed api calls. use this when the user needs read-only lookups (item details, price guides, order history, ratings) or guarded writes (inventory mutations, feedback, coupons, member notes). reads are instant; writes require explicit user confirmation and --yes flag.
required environment variables (oauth1 credentials):
BRICKLINK_API_CONSUMER_KEY: oauth consumer key from bricklink app settings.BRICKLINK_API_CONSUMER_SECRET: oauth consumer secret.BRICKLINK_API_TOKEN_VALUE: oauth token value for your bricklink account.BRICKLINK_API_TOKEN_SECRET: oauth token secret.optional override:
BRICKLINK_API_BASE_URL: defaults to https://api.bricklink.com/api/store/v1. change only if bricklink moves or you use a test endpoint.never print, commit, log, or paste the real oauth credentials. commands reference BRICKLINK_API_* variables only indirectly through the cli.
external connection:
authorization: oauth ... header auth, not query params or body creds.checked-in cli and references:
scripts/bricklink_cli.py: handles oauth signing, request dispatch, response parsing.references/openapi/bricklink.yaml: endpoint definitions, parameter bounds, response schemas.input: none. output: cli command list, argument syntax.
scripts/bricklink --help
input: command name, flags (e.g., --type SET --no 75192-1, --order-id 123456, --username example_user).
output: json response from bricklink api, pretty-printed or raw.
examples:
scripts/bricklink colors
scripts/bricklink color --color-id 11
scripts/bricklink categories
scripts/bricklink item --type SET --no 75192-1
scripts/bricklink item-price --type SET --no 75192-1 --guide-type sold --new-or-used N --currency-code EUR
scripts/bricklink item-colors --type PART --no 3001
scripts/bricklink item-mapping --type PART --no 3001 --color-id 5
scripts/bricklink element-mapping --element-id 4211111
scripts/bricklink inventory-list --item-type SET --status Y
scripts/bricklink orders --direction in --status PAID
scripts/bricklink order --order-id 123456
scripts/bricklink order-items --order-id 123456
scripts/bricklink order-messages --order-id 123456
scripts/bricklink order-feedback --order-id 123456
scripts/bricklink notifications
scripts/bricklink coupons
scripts/bricklink coupon --coupon-id 987654
scripts/bricklink shipping-methods
scripts/bricklink shipping-method --method-id 1
scripts/bricklink member-ratings --username example_user
scripts/bricklink member-notes --username example_user
scripts/bricklink feedback
scripts/bricklink feedback-view --feedback-id 555555
read-only commands never touch live state. safe to run anytime.
--dry-run (no credentials sent, no network call)input: command name, flags, --dry-run flag, --json payload for create/update/delete operations.
output: redacted request shape (credentials shown as env var names, not values), response shape, no side effects.
examples:
scripts/bricklink inventory-create --dry-run \
--json '{"item":{"type":"PART","no":"3001"},"color_id":5,"quantity":1,"unit_price":"0.12","new_or_used":"U"}'
scripts/bricklink inventory-update --dry-run --inventory-id 123456 \
--json '{"quantity":2,"unit_price":"0.15"}'
scripts/bricklink inventory-delete --dry-run --inventory-id 123456
scripts/bricklink order-status --dry-run --order-id 123456 --json '{"status":"PACKED"}'
scripts/bricklink feedback-create --dry-run --json '{"order_id":123456,"rating":"POSITIVE","comment":"Thank you"}'
scripts/bricklink feedback-reply --dry-run --feedback-id 555555 --json '{"comment":"Thanks for the feedback"}'
scripts/bricklink coupon-create --dry-run --json '{"buyer_name":"example_user","discount_rate":5}'
scripts/bricklink coupon-update --dry-run --coupon-id 987654 --json '{"discount_rate":10}'
scripts/bricklink coupon-delete --dry-run --coupon-id 987654
scripts/bricklink member-notes-update --dry-run --username example_user --json '{"note":"Asked about train parts"}'
scripts/bricklink member-notes-delete --dry-run --username example_user
input: dry-run output summary (target id, item, payload fields). output: user says "yes, do it" or "cancel".
restate:
PUT /inventories/123456).do not run the mutation until you see explicit yes from the user (e.g., "yes, update", "confirm", "do it").
--yes flaginput: command name, flags, --json payload, --yes flag.
output: http status, response body (inventory id, order status, coupon id, feedback id, etc.), or error.
examples:
scripts/bricklink inventory-create --yes --json "$INVENTORY_JSON"
scripts/bricklink inventory-update --yes --inventory-id 123456 --json "$PATCH_JSON"
scripts/bricklink inventory-delete --yes --inventory-id 123456
scripts/bricklink order-status --yes --order-id 123456 --json "$STATUS_JSON"
scripts/bricklink feedback-create --yes --json "$FEEDBACK_JSON"
scripts/bricklink coupon-create --yes --json "$COUPON_JSON"
scripts/bricklink member-notes-update --yes --username example_user --json "$NOTE_JSON"
input: resource id (inventory-id, order-id, coupon-id, username, etc.). output: current state of the resource.
examples:
scripts/bricklink inventory --inventory-id 123456
scripts/bricklink order --order-id 123456
scripts/bricklink coupon --coupon-id 987654
scripts/bricklink member-notes --username example_user
input: none (local, no network). output: python syntax valid, all tests pass, no trailing whitespace.
python3 -m py_compile scripts/bricklink_cli.py
scripts/bricklink inventory-delete --dry-run --inventory-id 123456
python3 -m unittest discover -s tests -p 'test_*.py'
scripts/validate-skills.sh
git diff --check
optional: read-only network check (only if all four BRICKLINK_API_* are set):
scripts/bricklink colors
summarize only response shape (status, top-level keys, rough counts). never paste account, order, inventory, member-note data or credential values.
if user asks for a read-only query (item, price, order, feedback, notification, coupon, shipping, member ratings): run the read-only command directly. no confirmation needed. safe to execute immediately.
if user asks to create, update, or delete inventory, order status, feedback, coupon, or member note:
first, check that all four BRICKLINK_API_* env vars are set. if any are missing, stop and tell the user which vars are missing. if set, draft the exact json payload, run --dry-run, show the output to the user, and wait for explicit confirmation ("yes", "confirm", "do it") before running --yes.
if user says "sell item", "list lot", "update my store", "delete inventory", "leave feedback", or "create coupon" but does not name a platform and both bricklink and brickowl are available in the conversation context: ask which marketplace (bricklink or brickowl) before touching anything. do not guess.
if user asks for a price estimate and does not specify guide-type, new-or-used, or currency:
set defaults explicitly: --guide-type sold (not stock), --new-or-used N (new, unless the user asks for used), --currency-code EUR (or user's currency). show the user the defaults you chose before running the query.
if user asks for item supersets or subsets and does not mention breaking minifigs or subsets: ask whether to break them (e.g., "should i expand minifigs into parts?" or "keep sets as-is?") before fetching. these flags change response shape.
if the user asks for large price breakdowns (e.g., "get prices for all 600 parts in set X"): ask for approval first. price fan-out can generate many api calls and hit rate limits. show the count and scope before executing.
if a read-only query returns an empty result set (no colors, no orders, no feedback, no coupons, no inventory): report the empty state clearly. do not retry or invent dummy data. empty is valid.
if the bricklink api returns a 401, 403, or invalid-signature error:
the credentials are wrong or expired. tell the user to check all four BRICKLINK_API_* env vars, re-auth in bricklink account settings, and regenerate tokens if needed.
if the bricklink api is slow (>5 second response) or times out: report the latency or timeout. do not auto-retry. ask the user whether to retry manually. bricklink may be under load.
if the user tries to delete an inventory lot, order, coupon, or member note: require immediate confirmation with the exact resource id and a plain-language summary of what will be deleted. deletions are permanent. do not proceed without explicit yes.
success means:
price_guide (price queries), color_id (item with colors), order_id (order queries), etc. http status 200. no errors.--yes: http status 200 or 201, response body includes created/updated resource id, timestamp, or confirmation flag. no errors.data format:
{"item":{"type":"PART"|"SET"|"MINIFIG","no":"<part-no>"},"color_id":5,"quantity":1,"unit_price":"0.12","new_or_used":"N"|"U","description":"...","remarks":"..."}.{"status":"PAID"|"PROCESSING"|"PACKED"|"SHIPPED"|"RECEIVED"}.{"order_id":123456,"rating":"POSITIVE"|"NEUTRAL"|"NEGATIVE","comment":"..."}.{"buyer_name":"username","discount_rate":5} (5 = 5% off).{"note":"custom text"}.no private account numbers, real order ids, inventory ids, or member usernames are written to logs or stdout during normal operation. --dry-run redacts credentials.
file locations:
scripts/bricklink or scripts/bricklink_cli.py.references/openapi/bricklink.yaml.tests/test_*.py.the user knows the skill worked when:
$BRICKLINK_API_TOKEN_VALUE, etc.), the request shape, and exits with code 0. no network call was made.--yes: the cli returns http 200 or 201, the response includes the resource id (inventory-id, coupon-id, etc.), a timestamp, or a success flag. the user can then run a read-only query to verify the change (e.g., inventory --inventory-id 123456). no errors.--yes: the cli returns http 204 or 200, a follow-up read query for the same resource returns 404 or empty. the lot, coupon, note, etc. is gone.if the skill fails:
BRICKLINK_API_* vars are not set. user must export them and retry.