Sign inTry it

Search Thomann for instruments and music gear.

Searches Thomann, Europe's largest music retailer, like its search page: brand and model, price in euros with the list price when reduced, stock status and delivery text, customer rating (0–5) and number of reviews, image and link. Sort by popularity, price, rating or newest. Prices are Thomann's German shop prices including VAT.

No reports yetRead-only, no login
Site
Thomann, Germany
Version
v1
Runs, last 7 days
No reports yet
sha256
2b9966af3e03…

Run it with your agent

after installing Wield

Ask in plain words. Your agent finds this recipe and calls it:

“Search Thomann for instruments and music gear.”

Read-only: it changes nothing on the site. No login needed.

{
  "tool": "run",
  "arguments": {
    "recipe_id": "thomann.de/search-products",
    "params": {
      "query": "westerngitarre",
      "sort": "price_low"
    }
  }
}

Requests

sent from your browser, in order
  1. 1GET/de/search_dir.html?ls&oa&pg&swThomann's search page. Its article list (price, stock, rating) is in the page as the JSON argument of tho.bootstrapModule('search.index', […]) in the script right after div.search; the HTML cards fill their prices from it.repeats, max 1

Parameters

from your agent
limitenum 25 | 50 | 100 = 25
pageinteger = 1
querystringrequiredWhat to look for, e.g. 'westerngitarre', 'shure sm58', 'focusrite scarlett'
sortenum "popularity" | "price_low" | "price_high" | "rating" | "newest" = "popularity"

Returns

to your agent
pageinteger
productsobject[]availability, image, in_stock, list_price_eur, name, price_eur, rating, reviews, title, url
querystring
totalinteger

Where it can send

  • www.thomann.de

Anything else is blocked by the extension.

Reads from your session

Nothing. Your browser attaches the site's cookies by itself.

Used only in requests to the addresses on the left. Never sent to wield.run or your agent.

Checks

a run passes when
  • length(output.products) == `25`
  • output.total > `100`
  • length(output.products[?price_eur > `0`]) == length(output.products)
  • output.products[*].price_eur == sort(output.products[*].price_eur)
  • length(output.products[?starts_with(url, 'https://www.thomann.de/de/') && ends_with(url, '.htm')]) == length(output.products)
  • length(output.products[?rating != `null` && (rating > `5` || rating < `0`)]) == `0`

Raw recipe

Served as canonical JSON from /api/v1/recipes/thomann.de/search-products, so its sha256 matches the ETag and the index.

Check it yourself
curl -s https://wield.run/api/v1/recipes/thomann.de/search-products | shasum -a 256
# 2b9966af3e03e992379e1e86b402cb37976bd42009ef1700057c889a028857ca
thomann.de/search-products.json, v1
{
  "description": "Searches Thomann, Europe's largest music retailer, like its search page: brand and model, price in euros with the list price when reduced, stock status and delivery text, customer rating (0–5) and number of reviews, image and link. Sort by popularity, price, rating or newest. Prices are Thomann's German shop prices including VAT.",
  "effect": "read",
  "id": "thomann.de/search-products",
  "keywords": [
    "thomann",
    "musikinstrumente",
    "gitarre",
    "e-gitarre",
    "keyboard",
    "schlagzeug",
    "mikrofon",
    "kopfhörer",
    "audio interface",
    "musical instruments",
    "guitar",
    "drums",
    "music gear",
    "studio"
  ],
  "output": {
    "schema": {
      "properties": {
        "page": {
          "type": "integer"
        },
        "products": {
          "items": {
            "properties": {
              "availability": {
                "description": "As Thomann shows it, e.g. 'Sofort lieferbar', 'In 3–4 Wochen lieferbar'",
                "type": [
                  "string",
                  "null"
                ]
              },
              "image": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "in_stock": {
                "type": "boolean"
              },
              "list_price_eur": {
                "description": "Struck-through or list price when the product is reduced",
                "type": [
                  "number",
                  "null"
                ]
              },
              "name": {
                "description": "Brand and model",
                "type": "string"
              },
              "price_eur": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "rating": {
                "description": "0–5 stars, null without reviews",
                "type": [
                  "number",
                  "null"
                ]
              },
              "reviews": {
                "type": "integer"
              },
              "title": {
                "description": "Thomann's longer product title",
                "type": [
                  "string",
                  "null"
                ]
              },
              "url": {
                "type": "string"
              }
            },
            "type": "object"
          },
          "type": "array"
        },
        "query": {
          "type": "string"
        },
        "total": {
          "type": [
            "integer",
            "null"
          ]
        }
      },
      "required": [
        "query",
        "products"
      ],
      "type": "object"
    },
    "value": "let $s = steps.search[0] in {query: params.query, total: $s.total || `0`, page: params.page || `1`, products: map(&{name: join(' ', [manufacturer || '', model || '']), title: title || `null`, price_eur: (price && to_number(price)) || `null`, list_price_eur: (was && to_number(was)) || `null`, in_stock: label == 'IN_STOCK', availability: availability || `null`, rating: (reviews > `0` && floor(rating * `5`) / `10`) || `null`, reviews: reviews || `0`, image: (image && join('', ['https://thumbs.static-thomann.de/thumb/thumb220x220/pics/prod/', image])) || `null`, url: join('', ['https://www.thomann.de/de/', file, '.htm'])}, $s.articles || `[]`)}"
  },
  "params": {
    "additionalProperties": false,
    "properties": {
      "limit": {
        "default": 25,
        "enum": [
          25,
          50,
          100
        ],
        "type": "integer"
      },
      "page": {
        "default": 1,
        "maximum": 20,
        "minimum": 1,
        "type": "integer"
      },
      "query": {
        "description": "What to look for, e.g. 'westerngitarre', 'shure sm58', 'focusrite scarlett'",
        "maxLength": 100,
        "minLength": 2,
        "type": "string"
      },
      "sort": {
        "default": "popularity",
        "enum": [
          "popularity",
          "price_low",
          "price_high",
          "rating",
          "newest"
        ],
        "type": "string"
      }
    },
    "required": [
      "query"
    ],
    "type": "object"
  },
  "provenance": {
    "method": "browser-inspect",
    "notes": "The search page /de/search_dir.html?sw=<query>&ls=<25|50|100>&pg=<page>&oa=<sort> is server-rendered, but the card prices and stock are filled in by script from the page's own data: tho.bootstrapModule('search.index', [{…articleListsSettings: {resultCount, articles: [{fileName, manufacturer, model, price.primary.rawPrice, price.retail/strikePrice, availability.{label, textShort}, rating.{rating (0–10), count}, mainImage.fileName}]}}, …]) in the script that follows div.search. strip_js takes that JSON array. Sort keys come from the page's own sort menu (smb popularity, pra/prd price, rat rating, rel newest). Rating is shown as stars (rating/10 × 5, one decimal). Images are links to Thomann's image host thumbs.static-thomann.de, which the recipe never calls. No sponsored products in search results.",
    "recorded_at": "2026-11-07T21:44:00+01:00",
    "recorded_by": "C4"
  },
  "requires_login": false,
  "schema": "https://wield.run/schema/recipe/v1.json",
  "site": {
    "country": "DE",
    "id": "thomann.de",
    "language": "de",
    "name": "Thomann",
    "origin": "https://www.thomann.de",
    "origins": [
      "https://www.thomann.de"
    ]
  },
  "steps": [
    {
      "description": "Thomann's search page. Its article list (price, stock, rating) is in the page as the JSON argument of tho.bootstrapModule('search.index', […]) in the script right after div.search; the HTML cards fill their prices from it.",
      "expect": {
        "content_type": "html",
        "status": [
          200
        ]
      },
      "extract": {
        "embedded_json": {
          "required": false,
          "selector": "div.search + script",
          "strip_js": true,
          "vars": {
            "articles": "[0].articleListsSettings.articles[].{file: fileName, manufacturer: manufacturer, model: model, title: texts.title, price: price.primary.rawPrice, currency: price.primary.currency.key, was: price.strikePrice.rawPrice || price.retail.rawPrice, label: availability.label, availability: availability.textShort, rating: rating.rating, reviews: rating.count, image: mainImage.fileName}",
            "total": "[0].articleListsSettings.resultCount"
          }
        }
      },
      "foreach": {
        "as": "f",
        "in": "let $s = params.sort || 'popularity' in [{oa: (`[[\"popularity\",\"smb\"],[\"price_low\",\"pra\"],[\"price_high\",\"prd\"],[\"rating\",\"rat\"],[\"newest\",\"rel\"]]`[?@[0] == $s] | [0][1]) || 'smb'}]",
        "max": 1
      },
      "id": "search",
      "request": {
        "headers": {
          "Accept": "text/html"
        },
        "method": "GET",
        "query": {
          "ls": "{{params.limit | default:25}}",
          "oa": "{{f.oa}}",
          "pg": "{{params.page | default:1}}",
          "sw": "{{params.query}}"
        },
        "url": "/de/search_dir.html"
      }
    }
  ],
  "task": "Search Thomann for instruments and music gear",
  "tos": {
    "notes": "robots.txt allows the search page (it only disallows filter URLs, baskets and wishlists; GPTBot and DataForSeoBot are disallowed entirely, which does not apply to a user's own agent). One request per call, the same page a person sees; no basket or wishlist actions.",
    "reviewed": false
  },
  "verify": {
    "checks": [
      "length(output.products) == `25`",
      "output.total > `100`",
      "length(output.products[?price_eur > `0`]) == length(output.products)",
      "output.products[*].price_eur == sort(output.products[*].price_eur)",
      "length(output.products[?starts_with(url, 'https://www.thomann.de/de/') && ends_with(url, '.htm')]) == length(output.products)",
      "length(output.products[?rating != `null` && (rating > `5` || rating < `0`)]) == `0`"
    ],
    "example_params": {
      "query": "westerngitarre",
      "sort": "price_low"
    },
    "max_ms": 4000
  },
  "version": 1
}