diff --git a/clldutils/badge.py b/clldutils/badge.py
index 14829b5..a74fca1 100644
--- a/clldutils/badge.py
+++ b/clldutils/badge.py
@@ -19,12 +19,8 @@ class Colors(object):
     blue = 'blue'
 
 
-def badge(subject, status, color, fmt='svg', markdown=True, **kw):
-    query = ''
-    if kw:
-        query = '?' + urlencode(kw)
+def badge(subject, status, color, fmt='svg', markdown=True, label=None, **kw):
+    label = label or ': '.join([subject, status])
     url = 'https://img.shields.io/badge/{0}-{1}-{2}.{3}{4}'.format(
-        quote(subject), quote(status), color, fmt, query)
-    if markdown:
-        return '![{0}]({1} "{0}")'.format(': '.join([subject, status]), url)
-    return url
+        quote(subject), quote(status), color, fmt, '?' + urlencode(kw) if kw else '')
+    return '![{0}]({1} "{0}")'.format(label, url) if markdown else url

The `badge` function should be more flexible
`badge.badge` should accept all atomic parts of the label/URL it creates as input argument; such that it exposes all functionality of the `shields.io` service.
diff --git a/clldutils/tests/test_badge.py b/clldutils/tests/test_badge.py
index 272560c..66bcabb 100644
--- a/clldutils/tests/test_badge.py
+++ b/clldutils/tests/test_badge.py
@@ -12,3 +12,4 @@ def test_badge():
         '![cov: 20%](https://img.shields.io/badge/cov-20%25-orange.svg "cov: 20%")'
     assert _badge(markdown=False, style='plastic') == \
         'https://img.shields.io/badge/cov-20%25-orange.svg?style=plastic'
+    assert '[abc]' in badge('subject', 'status', 'color', label='abc')

pip install -e .[dev]
parse_log_pytest
requirements.txt
nose coverage mock>=2.0 pytest
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
-e git+https://github.com/clld/clldutils.git@54679df634b93870ea9fec722a56b75e72017645#egg=clldutils
configparser==7.2.0
coverage==7.8.0
exceptiongroup==1.2.2
iniconfig==2.1.0
mock==5.2.0
nose==1.3.7
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
python-dateutil==2.9.0.post0
six==1.17.0
tabulate==0.9.0
tomli==2.2.1

name: clldutils
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - configparser==7.2.0
      - coverage==7.8.0
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - mock==5.2.0
      - nose==1.3.7
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - python-dateutil==2.9.0.post0
      - six==1.17.0
      - tabulate==0.9.0
      - tomli==2.2.1
prefix: /opt/conda/envs/clldutils

clldutils/tests/test_badge.py::test_badge
clldutils/badge.py
clldutils/badge.py