diff --git a/core/base-service/base-svg-scraping.spec.js b/core/base-service/base-svg-scraping.spec.js
index 15548e0ba6c90054ceec6e0adc456f3e7d61856c..7cc37ac3ea1b654f7df7f2b70d74dbf0a0c3003f 100644
--- a/core/base-service/base-svg-scraping.spec.js
+++ b/core/base-service/base-svg-scraping.spec.js
@@ -3,14 +3,11 @@
 const { expect } = require('chai')
 const sinon = require('sinon')
 const Joi = require('joi')
-const { makeBadgeData } = require('../../lib/badge-data')
 const makeBadge = require('../../gh-badges/lib/make-badge')
 const BaseSvgScrapingService = require('./base-svg-scraping')
 
 function makeExampleSvg({ label, message }) {
-  const badgeData = makeBadgeData('this is the label', {})
-  badgeData.text[1] = 'this is the result!'
-  return makeBadge(badgeData)
+  return makeBadge({ text: ['this is the label', 'this is the result!'] })
 }
 
 const schema = Joi.object({
diff --git a/core/base-service/legacy-request-handler.js b/core/base-service/legacy-request-handler.js
index 3deb6e56854eb00eef9bd95f4741d94472ffd479..78ee9ec98458e1ba2146e238ca4d4ec82a50f65a 100644
--- a/core/base-service/legacy-request-handler.js
+++ b/core/base-service/legacy-request-handler.js
@@ -6,7 +6,6 @@ const request = require('request')
 const queryString = require('query-string')
 const LruCache = require('../../gh-badges/lib/lru-cache')
 const makeBadge = require('../../gh-badges/lib/make-badge')
-const { makeBadgeData: getBadgeData } = require('../../lib/badge-data')
 const log = require('../server/log')
 const { setCacheHeaders } = require('./cache-headers')
 const {
@@ -15,6 +14,7 @@ const {
   ShieldsRuntimeError,
 } = require('./errors')
 const { makeSend } = require('./legacy-result-sender')
+const coalesceBadge = require('./coalesce-badge')
 
 // We avoid calling the vendor's server for computation of the information in a
 // number of badges.
@@ -38,8 +38,8 @@ vendorDomain.on('error', err => {
   log.error('Vendor hook error:', err.stack)
 })
 
-// These query parameters are available to any badge. For the most part they
-// are used by makeBadgeData (see `lib/badge-data.js`) and related functions.
+// These query parameters are available to any badge. They are handled by
+// `coalesceBadge`.
 const globalQueryParams = new Set([
   'label',
   'style',
@@ -169,15 +169,18 @@ function handleRequest(cacheHeaderConfig, handlerOptions) {
         return
       }
       ask.res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
-      const badgeData = getBadgeData('vendor', filteredQueryParams)
-      badgeData.text[1] = 'unresponsive'
+      const badgeData = coalesceBadge(
+        filteredQueryParams,
+        { label: 'vendor', message: 'unresponsive' },
+        {}
+      )
+      const svg = makeBadge(badgeData)
       let extension
       try {
         extension = match[0].split('.').pop()
       } catch (e) {
         extension = 'svg'
       }
-      const svg = makeBadge(badgeData)
       setCacheHeadersOnResponse(ask.res)
       makeSend(extension, ask.res, end)(svg)
     }, 25000)
diff --git a/core/base-service/legacy-request-handler.spec.js b/core/base-service/legacy-request-handler.spec.js
index 84dd021a8e08892b4cab7076151579f9c6128b44..2a8b57e65f9be75ba982cc39f02496655e40e33e 100644
--- a/core/base-service/legacy-request-handler.spec.js
+++ b/core/base-service/legacy-request-handler.spec.js
@@ -5,7 +5,7 @@ const fetch = require('node-fetch')
 const nock = require('nock')
 const portfinder = require('portfinder')
 const Camp = require('camp')
-const { makeBadgeData: getBadgeData } = require('../../lib/badge-data')
+const coalesceBadge = require('./coalesce-badge')
 const {
   handleRequest,
   clearRequestCache,
@@ -19,17 +19,31 @@ async function performTwoRequests(baseUrl, first, second) {
 
 function fakeHandler(queryParams, match, sendBadge, request) {
   const [, someValue, format] = match
-  const badgeData = getBadgeData('testing', queryParams)
-  badgeData.text[1] = someValue
+  const badgeData = coalesceBadge(
+    queryParams,
+    {
+      label: 'testing',
+      message: someValue,
+    },
+    {}
+  )
   sendBadge(format, badgeData)
 }
 
 function createFakeHandlerWithCacheLength(cacheLengthSeconds) {
   return function fakeHandler(queryParams, match, sendBadge, request) {
     const [, someValue, format] = match
-    const badgeData = getBadgeData('testing', queryParams)
-    badgeData.text[1] = someValue
-    badgeData.cacheLengthSeconds = cacheLengthSeconds
+    const badgeData = coalesceBadge(
+      queryParams,
+      {
+        label: 'testing',
+        message: someValue,
+      },
+      {},
+      {
+        _cacheLength: cacheLengthSeconds,
+      }
+    )
     sendBadge(format, badgeData)
   }
 }
@@ -37,13 +51,21 @@ function createFakeHandlerWithCacheLength(cacheLengthSeconds) {
 function fakeHandlerWithNetworkIo(queryParams, match, sendBadge, request) {
   const [, someValue, format] = match
   request('https://www.google.com/foo/bar', (err, res, buffer) => {
-    const badgeData = getBadgeData('testing', queryParams)
+    let message
     if (err) {
-      badgeData.text[1] = err.prettyMessage
-      sendBadge(format, badgeData)
-      return
+      message = err.prettyMessage
+    } else {
+      message = someValue
     }
-    badgeData.text[1] = someValue
+    const badgeData = coalesceBadge(
+      queryParams,
+      {
+        label: 'testing',
+        message,
+        format,
+      },
+      {}
+    )
     sendBadge(format, badgeData)
   })
 }
diff --git a/core/server/server.js b/core/server/server.js
index f175e112f2b90ca723d2150b7d478e493148a2cd..de35d017059eec517170038e4f3bf87493850358 100644
--- a/core/server/server.js
+++ b/core/server/server.js
@@ -8,7 +8,6 @@ const Joi = require('joi')
 const Camp = require('camp')
 const makeBadge = require('../../gh-badges/lib/make-badge')
 const GithubConstellation = require('../../services/github/github-constellation')
-const { makeBadgeData } = require('../../lib/badge-data')
 const suggest = require('../../services/suggest')
 const { loadServiceClasses } = require('../base-service/loader')
 const { makeSend } = require('../base-service/legacy-result-sender')
@@ -165,13 +164,12 @@ module.exports = class Server {
     const { camp } = this
 
     camp.notfound(/\.(svg|png|gif|jpg|json)/, (query, match, end, request) => {
-      const format = match[1]
-      const badgeData = makeBadgeData('404', query)
-      badgeData.text[1] = 'badge not found'
-      badgeData.colorB = 'red'
-      // Add format to badge data.
-      badgeData.format = format
-      const svg = makeBadge(badgeData)
+      const [, format] = match
+      const svg = makeBadge({
+        text: ['404', 'badge not found'],
+        color: 'red',
+        format,
+      })
       makeSend(format, request.res, end)(svg)
     })
 
diff --git a/lib/badge-data.js b/lib/badge-data.js
deleted file mode 100644
index 8b02dbda320805d39edea7a0949cfbcc4a297beb..0000000000000000000000000000000000000000
--- a/lib/badge-data.js
+++ /dev/null
@@ -1,53 +0,0 @@
-'use strict'
-
-const coalesce = require('../core/base-service/coalesce')
-const toArray = require('../core/base-service/to-array')
-const { makeLogo } = require('./logos')
-
-function makeLabel(defaultLabel, overrides) {
-  return `${
-    overrides.label === undefined
-      ? (defaultLabel || '').toLowerCase()
-      : overrides.label
-  }`
-}
-
-// Generate the initial badge data. Pass the URL query parameters, which
-// override the default label.
-//
-// The following parameters are supported:
-//
-//   - label
-//   - style
-//   - logo
-//   - logoWidth
-//   - link
-//   - color and colorB
-//   - labelColor and colorA
-//   - maxAge
-//   - cacheSeconds
-//
-// Note: `maxAge` and `cacheSeconds` are handled by cache(), not this function.
-function makeBadgeData(defaultLabel, overrides) {
-  const colorA = coalesce(overrides.labelColor, overrides.colorA)
-  const colorB = coalesce(overrides.color, overrides.colorB)
-
-  return {
-    text: [makeLabel(defaultLabel, overrides), 'n/a'],
-    colorscheme: 'lightgrey',
-    template: overrides.style,
-    logo: makeLogo(undefined, overrides),
-    logoPosition: +overrides.logoPosition,
-    logoWidth: +overrides.logoWidth,
-    links: toArray(overrides.link),
-    // Scoutcamp sometimes turns these into numbers.
-    colorA: typeof colorA === 'number' ? `${colorA}` : colorA,
-    colorB: typeof colorB === 'number' ? `${colorB}` : colorB,
-  }
-}
-
-module.exports = {
-  toArray,
-  makeLabel,
-  makeBadgeData,
-}
diff --git a/lib/badge-data.spec.js b/lib/badge-data.spec.js
deleted file mode 100644
index 70d478ded967cc9609941e1da2198717181ebe91..0000000000000000000000000000000000000000
--- a/lib/badge-data.spec.js
+++ /dev/null
@@ -1,39 +0,0 @@
-'use strict'
-
-const { test, given } = require('sazerac')
-const { makeLabel, makeBadgeData } = require('./badge-data')
-
-describe('Badge data helpers', function() {
-  test(makeLabel, () => {
-    given('my badge', {}).expect('my badge')
-    given('My bAdge', {}).expect('my badge')
-    given('my badge', { label: 'no, my badge' }).expect('no, my badge')
-    given('my badge', { label: 'no, MY badge' }).expect('no, MY badge')
-    given('my badge', { label: false }).expect('false')
-    given('my badge', { label: 0 }).expect('0')
-    given('my badge', { label: '' }).expect('')
-  })
-
-  test(makeBadgeData, () => {
-    given('my badge', {
-      label: 'no, my badge',
-      style: 'flat-square',
-      logo: 'image/svg+xml;base64,PHN2ZyB4bWxu',
-      logoPosition: 10,
-      logoWidth: '25',
-      link: 'https://example.com/',
-      colorA: 'blue',
-      colorB: 'f00bae',
-    }).expect({
-      text: ['no, my badge', 'n/a'],
-      colorscheme: 'lightgrey',
-      template: 'flat-square',
-      logo: 'data:image/svg+xml;base64,PHN2ZyB4bWxu',
-      logoPosition: 10,
-      logoWidth: 25,
-      links: ['https://example.com/'],
-      colorA: 'blue',
-      colorB: 'f00bae',
-    })
-  })
-})