Sign inTry it

Find local businesses by trade and city on 11880.

Searches 11880.com, the German business directory, for a trade or name in a city: business name, trades, address, public phone number, whether it is open now, star rating and number of reviews, the paid entry tier it shows (gold, silber, bronze, branchen; ranking can favour paid tiers), and a link to the entry. Up to 50 results with the total number of matches.

No reports yetRead-only, no login
Site
11880, Germany
Version
v1
Runs, last 7 days
No reports yet
sha256
96dd2d2878af…

Run it with your agent

after installing Wield

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

“Find local businesses by trade and city on 11880.”

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

{
  "tool": "run",
  "arguments": {
    "recipe_id": "11880.com/search-businesses",
    "params": {
      "what": "zahnarzt",
      "where": "berlin"
    }
  }
}

Requests

sent from your browser, in order
  1. 1GET/suche/{{f.what | urlencode}}/{{f.where | urlencode}}11880's search page (/suche/<what>/<where>), server-rendered with up to 50 li.search-result-entry-item entries and the hit count.repeats, max 1

Parameters

from your agent
whatstringrequiredTrade or business name, e.g. 'zahnarzt', 'elektriker', 'friseur'
wherestringrequiredCity or postcode as 11880 names it, e.g. 'berlin', 'köln', 'frankfurt', '80331'. A name 11880 shortens (frankfurt am main → frankfurt) answers a redirect, which the executor does not follow.

Returns

to your agent
businessesobject[]address, listing_tier, name, open_now, opening, phone, rating, reviews, trades, url
totalinteger
whatstring
wherestring

Where it can send

  • www.11880.com

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.businesses) == `50`
  • output.total > `1000`
  • length(output.businesses[?starts_with(url, 'https://www.11880.com/branchenbuch/')]) == length(output.businesses)
  • length(output.businesses[?phone != `null`]) > `40`
  • length(output.businesses[?contains(address || '', 'Berlin')]) == length(output.businesses)

Raw recipe

Served as canonical JSON from /api/v1/recipes/11880.com/search-businesses, so its sha256 matches the ETag and the index.

Check it yourself
curl -s https://wield.run/api/v1/recipes/11880.com/search-businesses | shasum -a 256
# 96dd2d2878af5fa748cf61a5bc9a80651671f6b10c500f1ee8bdb213f6118858
11880.com/search-businesses.json, v1
{
  "description": "Searches 11880.com, the German business directory, for a trade or name in a city: business name, trades, address, public phone number, whether it is open now, star rating and number of reviews, the paid entry tier it shows (gold, silber, bronze, branchen; ranking can favour paid tiers), and a link to the entry. Up to 50 results with the total number of matches.",
  "effect": "read",
  "id": "11880.com/search-businesses",
  "keywords": [
    "11880",
    "branchenbuch",
    "firmen",
    "telefonnummer",
    "adresse",
    "öffnungszeiten",
    "bewertungen",
    "handwerker",
    "zahnarzt",
    "local business",
    "directory",
    "phone number",
    "reviews",
    "opening hours"
  ],
  "output": {
    "schema": {
      "properties": {
        "businesses": {
          "items": {
            "properties": {
              "address": {
                "description": "Street, postcode, city (district)",
                "type": [
                  "string",
                  "null"
                ]
              },
              "listing_tier": {
                "description": "Paid entry tier 11880 shows: gold, silber, bronze, branchen; null for a basic entry",
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": "string"
              },
              "open_now": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "opening": {
                "description": "As shown, e.g. 'Geschlossen', 'Geöffnet'",
                "type": [
                  "string",
                  "null"
                ]
              },
              "phone": {
                "description": "The business's public number",
                "type": [
                  "string",
                  "null"
                ]
              },
              "rating": {
                "description": "Stars out of 5",
                "type": [
                  "number",
                  "null"
                ]
              },
              "reviews": {
                "type": "integer"
              },
              "trades": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "url": {
                "type": "string"
              }
            },
            "type": "object"
          },
          "type": "array"
        },
        "total": {
          "type": [
            "integer",
            "null"
          ]
        },
        "what": {
          "type": "string"
        },
        "where": {
          "type": "string"
        }
      },
      "required": [
        "what",
        "where",
        "businesses"
      ],
      "type": "object"
    },
    "value": "{what: params.what, where: params.where, total: (steps.search[0].total && to_number(replace(steps.search[0].total, '.', ''))) || `0`, businesses: map(&(let $oc = open_class || '' in {name: name, trades: trades || `null`, address: address || `null`, phone: phone || `null`, open_now: (`[[\"--closed\", false], [\"--open\", true]]`[?contains($oc, @[0])] | [0][1]), opening: opening || `null`, rating: (stars && to_number(split(stars, ' ')[0])) || `null`, reviews: (reviews && to_number(replace(split(reviews, ' ')[0], '(', ''))) || `0`, listing_tier: (tier && lower(split(tier, '-')[0])) || `null`, url: join('', ['https://www.11880.com', href])}), steps.search[0].entries[?href != `null`] || `[]`)}"
  },
  "params": {
    "additionalProperties": false,
    "properties": {
      "what": {
        "description": "Trade or business name, e.g. 'zahnarzt', 'elektriker', 'friseur'",
        "maxLength": 60,
        "minLength": 2,
        "type": "string"
      },
      "where": {
        "description": "City or postcode as 11880 names it, e.g. 'berlin', 'köln', 'frankfurt', '80331'. A name 11880 shortens (frankfurt am main → frankfurt) answers a redirect, which the executor does not follow.",
        "maxLength": 60,
        "minLength": 2,
        "type": "string"
      }
    },
    "required": [
      "what",
      "where"
    ],
    "type": "object"
  },
  "provenance": {
    "method": "browser-inspect",
    "notes": "The search page /suche/<what>/<where> is server-rendered: span#hit-count, then li.search-result-entry-item entries with h2 name, a.entry-detail-link (/branchenbuch/<city>/<id>/<slug>.html), .trades-list, a .result-list-entry-signet whose title names the paid entry tier (GOLD-, SILBER-, BRONZE-, BRANCHEN-Eintrag), stars as screen-reader text ('5 von 5 Sternen') and '(n Bewertungen)', .result-list-entry-opening-hours with a --closed or --open class, .result-list-entry-address and .result-list-entry-phone-number__label. Umlauts in the path are written ae/oe/ue/ss as the site does (köln answers 301 to koeln, which the executor does not follow). Multi-word city names are canonicalised by a redirect too (frankfurt am main → frankfurt); the param description says to use the short name. Entries are not labelled as ads, so none are dropped; the tier is returned instead.",
    "recorded_at": "2026-11-07T22:33:00+01:00",
    "recorded_by": "C4"
  },
  "requires_login": false,
  "schema": "https://wield.run/schema/recipe/v1.json",
  "site": {
    "country": "DE",
    "id": "11880.com",
    "language": "de",
    "name": "11880",
    "origin": "https://www.11880.com",
    "origins": [
      "https://www.11880.com"
    ]
  },
  "steps": [
    {
      "description": "11880's search page (/suche/<what>/<where>), server-rendered with up to 50 li.search-result-entry-item entries and the hit count.",
      "expect": {
        "content_type": "html",
        "status": [
          200
        ]
      },
      "extract": {
        "html": {
          "total": {
            "selector": "#hit-count"
          }
        },
        "html_items": {
          "entries": {
            "fields": {
              "address": {
                "selector": ".result-list-entry-address"
              },
              "href": {
                "attr": "href",
                "selector": "a.entry-detail-link"
              },
              "name": {
                "selector": "h2.result-list-entry-title__headline"
              },
              "open_class": {
                "attr": "class",
                "selector": ".result-list-entry-opening-hours"
              },
              "opening": {
                "selector": ".result-list-entry-opening-hours"
              },
              "phone": {
                "selector": ".result-list-entry-phone-number__label"
              },
              "reviews": {
                "selector": ".result-list-entry-stars__count"
              },
              "stars": {
                "selector": ".result-list-entry-stars .sr-only"
              },
              "tier": {
                "attr": "title",
                "selector": ".result-list-entry-signet"
              },
              "trades": {
                "selector": ".trades-list"
              }
            },
            "max": 50,
            "selector": "li.search-result-entry-item"
          }
        }
      },
      "foreach": {
        "as": "f",
        "in": "[{what: replace(replace(replace(replace(lower(trim(params.what)), 'ä', 'ae'), 'ö', 'oe'), 'ü', 'ue'), 'ß', 'ss'), where: replace(replace(replace(replace(lower(trim(params.where)), 'ä', 'ae'), 'ö', 'oe'), 'ü', 'ue'), 'ß', 'ss')}]",
        "max": 1
      },
      "id": "search",
      "request": {
        "headers": {
          "Accept": "text/html"
        },
        "method": "GET",
        "url": "/suche/{{f.what | urlencode}}/{{f.where | urlencode}}"
      }
    }
  ],
  "task": "Find local businesses by trade and city on 11880",
  "tos": {
    "notes": "robots.txt allows /suche (it disallows /ajax/, /form, /login and similar) and has no rules for Claude agents or AI content signals. One request per call; no calls, messages or reviews. Business phone numbers and addresses are the public entries the directory publishes.",
    "reviewed": false
  },
  "verify": {
    "checks": [
      "length(output.businesses) == `50`",
      "output.total > `1000`",
      "length(output.businesses[?starts_with(url, 'https://www.11880.com/branchenbuch/')]) == length(output.businesses)",
      "length(output.businesses[?phone != `null`]) > `40`",
      "length(output.businesses[?contains(address || '', 'Berlin')]) == length(output.businesses)"
    ],
    "example_params": {
      "what": "zahnarzt",
      "where": "berlin"
    },
    "max_ms": 4000
  },
  "version": 1
}