A small Go service and CLI that fetches North Hertfordshire District Council (NHDC) bin collection dates, and exposes the results via:
- A terminal-friendly CLI (bindicatwo query)
- A lightweight HTTP server (bindicatwo serve) that returns JSON
This project pairs with the corresponding firmware client here:
- https://github.com/robberwick/bindicatwo-client (see its README for device setup and OTA expectations)
- What it does
- Quick start
- Install
- Configuration (file and environment)
- CLI usage
- Searching for addresses by postcode
- Querying bin schedules
- HTTP server usage
- Authentication (API keys)
- Rate limiting and caching
- OTA firmware endpoints
- Development
Given an address or postcode, bindicatwo resolves your specific address on NHDC's website, scrapes upcoming bin collections, and outputs a normalized schedule. The HTTP API is suitable for dashboards, microcontrollers, and home automations.
-
Search for addresses by postcode:
- bindicatwo search -p "SG4 0JH" # list all addresses for postcode
- bindicatwo search -p "SG4 0JH" -i # interactive: select an address
- bindicatwo search -p "SG4 0JH" -j # JSON output
-
CLI one-off query:
- bindicatwo query --uprn 100080795976 # human-readable output
- bindicatwo query -u 100080795976 -j # JSON output
-
Run HTTP server on port 8080:
- bindicatwo serve
- curl "http://127.0.0.1:8080/schedule/100080795976" -H "X-API-Key: " # if keys configured
- curl "http://127.0.0.1:8080/schedule?uprn=100080795976" -H "X-API-Key: " # backward compatible query param
-
Create a config file and set defaults:
- bindicatwo config init # interactive setup (enter UPRN or '?' to search by postcode)
- bindicatwo config set uprn 100080795976 # set UPRN directly
Requires Go 1.21+.
- go install github.com/robberwick/bindicatwo-api/cmd/bindicatwo@latest
This provides the bindicatwo binary in your GOPATH/bin or GOBIN.
Configuration is handled by Viper with three sources in priority order:
- Flags
- Environment variables
- Config file
Config file default location and name:
- %USERPROFILE%.config\bindicatwo\config.yaml (Windows)
- $HOME/.config/bindicatwo/config.yaml (Linux/macOS)
You can also pass a custom file with --config path/to/config.yaml.
Environment variable prefix for generic keys is BINDICATWO_. For example, BINDICATWO_SEARCH sets the default search query for CLI usage. The server subcommand also binds a few un-prefixed env vars for typical hosting environments (see below).
To create and manage the config file:
- bindicatwo config init # interactive (enter UPRN or '?' to search by postcode)
- bindicatwo config path # show path
- bindicatwo config get # show values
- bindicatwo config set # set a value
- bindicatwo config unset # delete a key
- bindicatwo config api-keys ... # manage API keys (see Authentication)
The interactive config init prompts for a UPRN. Enter '?' to search for your address by
postcode instead. The postcode search will call the Cloud9 API to fetch matching addresses,
allow you to select one from the list, and automatically set the UPRN in your config.
Supported config keys:
- uprn: default UPRN (Unique Property Reference Number)
- json: default output mode for CLI (true/false)
- firmware_enabled: enable /firmware/* endpoints on the HTTP server
- firmware_version: string served at /firmware/version.txt
- firmware_file: path to a firmware binary served at /firmware/bindicatwo_firmware.bin
- api_key: single API key for HTTP auth (optional)
- api_keys: array of API keys for HTTP auth (optional)
The CLI is provided by the root bindicatwo command with subcommands.
Use the search subcommand to find addresses and their UPRNs by UK postcode:
- bindicatwo search [flags]
- --postcode, -p: UK postcode to search for (required)
- --json, -j: output JSON instead of human-readable
- --interactive, -i: interactive mode to select an address from the list
- --config: path to config file (overrides default search path)
Examples:
- bindicatwo search -p "SG4 0JH" # list all addresses for this postcode
- bindicatwo search -p "SG4 0JH" -i # select an address interactively
- bindicatwo search -p "SG4 0JH" -j # output as JSON
The search command queries the Cloud9 Technologies API and returns all matching addresses with their UPRNs. Use interactive mode (-i) to select an address and display just its UPRN.
- bindicatwo query [flags]
- --uprn, -u: UPRN (Unique Property Reference Number)
- --json, -j: output JSON instead of human-readable
- --config: path to config file (overrides default search path)
Environment variables for CLI defaults (via Viper prefix):
- BINDICATWO_UPRN, BINDICATWO_JSON
Examples:
- bindicatwo query -u 100080795976 # human-readable output
- bindicatwo query -u 100080795976 -j # JSON output
JSON shape returned by --json is an array of items with normalized fields designed for machines. Relative fields (e.g., daysUntil, isToday, isTomorrow) are computed by the tool before printing.
Start the server:
- bindicatwo serve [flags]
Default listen address is 127.0.0.1:8080. Change with --addr and --port or environment variables.
Endpoints:
-
GET /schedule/{uprn}
- Path parameter:
- uprn: the Unique Property Reference Number (e.g., 100080795976)
- Returns: JSON array of upcoming collections. Relative fields are included.
- Authentication: optional; see Authentication section.
- Example: GET /schedule/100080795976
- Path parameter:
-
GET / or /schedule (backward compatible)
- Query parameters:
- uprn (also accepts u, id)
- Returns: JSON array of upcoming collections. Relative fields are included.
- Authentication: optional; see Authentication section.
- Example: GET /schedule?uprn=100080795976
- Query parameters:
-
GET /healthz
- Returns 200 OK with a minimal body.
CORS:
- --cors "*" to allow all origins, or pass a comma-separated list of allowed origins.
Server flags and environment variables:
- --addr (ADDR): listen host (default 127.0.0.1)
- --port (PORT): listen port (default 8080; use 0 for an ephemeral port)
- --cache-ttl (CACHE_TTL): cache lifetime for identical queries (default 15m)
- --cors (CORS_ORIGINS): CORS allowed origins: "*" or CSV
- --rate-rps (RATE_RPS): upstream requests per second (default 1.0)
- --rate-burst (RATE_BURST): burst capacity (default 5)
- --firmware-enable (FIRMWARE_ENABLE): enable OTA endpoints
- --firmware-version (FIRMWARE_VERSION): version string for /firmware/version.txt
- --firmware-file (FIRMWARE_FILE): path to binary served by /firmware/bindicatwo_firmware.bin
Note: The CLI-level env vars use the BINDICATWO_ prefix (e.g., BINDICATWO_SEARCH), but the server-specific hosting vars use the unprefixed names in parentheses above for convenience.
If any API key is configured, the schedule endpoints are required to provide a valid API key in order to receive a response. If none are set, auth is disabled.
How to configure:
- In the config file, either:
- api_key: "your-key"
- api_keys: ["key1", "key2", ...]
- Or via environment:
- API_KEYS="key1,key2" (CSV)
- API_KEY="your-key"
How to manage keys via CLI:
- bindicatwo config api-keys list
- bindicatwo config api-keys add
- bindicatwo config api-keys remove
- bindicatwo config api-keys generate [--length 32] # prints generated key
How to authenticate requests:
- Header: X-API-Key:
- Or: Authorization: Bearer
- Or: Query string: ?api_key= (or ?apikey=)
- The server uses an in-process token bucket to limit upstream requests (configurable via RATE_RPS and RATE_BURST).
- Successful schedules are cached per (search, prefer) key for --cache-ttl to reduce upstream load. Empty upstream results are intentionally not cached.
These are useful for the companion bindicatwo-client project. Disabled by default.
Enable and configure:
- bindicatwo serve --firmware-enable --firmware-version "1.2.3" --firmware-file ./path/to/bindicatwo_firmware.bin
- Or via env: FIRMWARE_ENABLE=1, FIRMWARE_VERSION=1.2.3, FIRMWARE_FILE=/path/to/bindicatwo_firmware.bin
Endpoints when enabled:
- GET /firmware/version.txt -> plain text of the version string
- GET /firmware/bindicatwo_firmware.bin -> application/octet-stream firmware binary (with Content-Disposition for download)
- Go 1.21+
- Run locally:
- go run . query -s "SG4 9TY"
- go run . serve --port 8080
- Tests:
- go test ./...
- Firmware/device client: https://github.com/robberwick/bindicatwo-client
MIT