diff --git a/services/opencollective/opencollective-all.service.js b/services/opencollective/opencollective-all.service.js
index dac3229f9779114d37e322167158ded01a6ec5c2..38e6ecb7edf8b911caee7c93e36a68cad351a11e 100644
--- a/services/opencollective/opencollective-all.service.js
+++ b/services/opencollective/opencollective-all.service.js
@@ -1,16 +1,20 @@
+import { pathParams } from '../index.js'
 import OpencollectiveBase from './opencollective-base.js'
 
 export default class OpencollectiveAll extends OpencollectiveBase {
   static route = this.buildRoute('all')
 
-  static examples = [
-    {
-      title: 'Open Collective backers and sponsors',
-      namedParams: { collective: 'shields' },
-      staticPreview: this.render(35),
-      keywords: ['opencollective'],
+  static openApi = {
+    '/opencollective/all/{collective}': {
+      get: {
+        summary: 'Open Collective backers and sponsors',
+        parameters: pathParams({
+          name: 'collective',
+          example: 'shields',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = {
     label: 'backers and sponsors',
diff --git a/services/opencollective/opencollective-backers.service.js b/services/opencollective/opencollective-backers.service.js
index 8c1f7321e76e074e97b21adae801d42e3345ddb4..6e5204a42ae012c6b898305f3de5397d81fa58cd 100644
--- a/services/opencollective/opencollective-backers.service.js
+++ b/services/opencollective/opencollective-backers.service.js
@@ -1,16 +1,20 @@
+import { pathParams } from '../index.js'
 import OpencollectiveBase from './opencollective-base.js'
 
 export default class OpencollectiveBackers extends OpencollectiveBase {
   static route = this.buildRoute('backers')
 
-  static examples = [
-    {
-      title: 'Open Collective backers',
-      namedParams: { collective: 'shields' },
-      staticPreview: this.render(25),
-      keywords: ['opencollective'],
+  static openApi = {
+    '/opencollective/backers/{collective}': {
+      get: {
+        summary: 'Open Collective backers',
+        parameters: pathParams({
+          name: 'collective',
+          example: 'shields',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = {
     label: 'backers',
diff --git a/services/opencollective/opencollective-sponsors.service.js b/services/opencollective/opencollective-sponsors.service.js
index 30d486dbdceccb890f62a79f50c41f7019a379af..c8246370a85e7cf669e87b1cea38a490b9f63838 100644
--- a/services/opencollective/opencollective-sponsors.service.js
+++ b/services/opencollective/opencollective-sponsors.service.js
@@ -1,16 +1,20 @@
+import { pathParams } from '../index.js'
 import OpencollectiveBase from './opencollective-base.js'
 
 export default class OpencollectiveSponsors extends OpencollectiveBase {
   static route = this.buildRoute('sponsors')
 
-  static examples = [
-    {
-      title: 'Open Collective sponsors',
-      namedParams: { collective: 'shields' },
-      staticPreview: this.render(10),
-      keywords: ['opencollective'],
+  static openApi = {
+    '/opencollective/sponsors/{collective}': {
+      get: {
+        summary: 'Open Collective sponsors',
+        parameters: pathParams({
+          name: 'collective',
+          example: 'shields',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = {
     label: 'sponsors',
diff --git a/services/opm/opm-version.service.js b/services/opm/opm-version.service.js
index e05358862870bbc23464d9a9f05978be5640fd8f..03d66950b66c09fcf13d118a5f5adc27cec1d59c 100644
--- a/services/opm/opm-version.service.js
+++ b/services/opm/opm-version.service.js
@@ -1,5 +1,5 @@
 import { renderVersionBadge } from '../version.js'
-import { BaseService, NotFound, InvalidResponse } from '../index.js'
+import { BaseService, NotFound, InvalidResponse, pathParams } from '../index.js'
 
 export default class OpmVersion extends BaseService {
   static category = 'version'
@@ -9,16 +9,23 @@ export default class OpmVersion extends BaseService {
     pattern: ':user/:moduleName',
   }
 
-  static examples = [
-    {
-      title: 'OPM',
-      namedParams: {
-        user: 'openresty',
-        moduleName: 'lua-resty-lrucache',
+  static openApi = {
+    '/opm/v/{user}/{moduleName}': {
+      get: {
+        summary: 'OPM Version',
+        parameters: pathParams(
+          {
+            name: 'user',
+            example: 'openresty',
+          },
+          {
+            name: 'moduleName',
+            example: 'lua-resty-lrucache',
+          },
+        ),
       },
-      staticPreview: renderVersionBadge({ version: 'v0.08' }),
     },
-  ]
+  }
 
   static defaultBadgeData = {
     label: 'opm',
diff --git a/services/ossf-scorecard/ossf-scorecard.service.js b/services/ossf-scorecard/ossf-scorecard.service.js
index b729f52c13b5c2583047e45d9d7be9b244fa0364..1ee57a04017b976d5f025e37862ebfdc32f914da 100644
--- a/services/ossf-scorecard/ossf-scorecard.service.js
+++ b/services/ossf-scorecard/ossf-scorecard.service.js
@@ -1,5 +1,5 @@
 import Joi from 'joi'
-import { BaseJsonService } from '../index.js'
+import { BaseJsonService, pathParams } from '../index.js'
 import { colorScale } from '../color-formatters.js'
 
 const schema = Joi.object({
@@ -16,17 +16,27 @@ export default class OSSFScorecard extends BaseJsonService {
 
   static route = { base: 'ossf-scorecard', pattern: ':host/:orgName/:repoName' }
 
-  static examples = [
-    {
-      title: 'OSSF-Scorecard Score',
-      namedParams: {
-        host: 'github.com',
-        orgName: 'rohankh532',
-        repoName: 'org-workflow-add',
+  static openApi = {
+    '/ossf-scorecard/{host}/{orgName}/{repoName}': {
+      get: {
+        summary: 'OSSF-Scorecard Score',
+        parameters: pathParams(
+          {
+            name: 'host',
+            example: 'github.com',
+          },
+          {
+            name: 'orgName',
+            example: 'rohankh532',
+          },
+          {
+            name: 'repoName',
+            example: 'org-workflow-add',
+          },
+        ),
       },
-      staticPreview: this.render({ score: '7.5' }),
     },
-  ]
+  }
 
   static defaultBadgeData = { label: 'score' }
 
diff --git a/services/powershellgallery/powershellgallery.service.js b/services/powershellgallery/powershellgallery.service.js
index ffa57ed236939803745b872b86f7b8c7590c7e94..26c8621614064a361f06bf0b4d4989aa2a891cb1 100644
--- a/services/powershellgallery/powershellgallery.service.js
+++ b/services/powershellgallery/powershellgallery.service.js
@@ -1,5 +1,5 @@
 import { fetch, createServiceFamily } from '../nuget/nuget-v2-service-family.js'
-import { BaseXmlService } from '../index.js'
+import { BaseXmlService, pathParams } from '../index.js'
 
 const WINDOWS_TAG_NAME = 'windows'
 const MACOS_TAG_NAME = 'macos'
@@ -32,15 +32,17 @@ class PowershellGalleryPlatformSupport extends BaseXmlService {
     pattern: ':packageName',
   }
 
-  static examples = [
-    {
-      title: 'PowerShell Gallery',
-      namedParams: { packageName: 'PackageManagement' },
-      staticPreview: this.render({
-        platforms: ['windows', 'macos', 'linux'],
-      }),
+  static openApi = {
+    '/powershellgallery/p/{packageName}': {
+      get: {
+        summary: 'PowerShell Gallery Platform Support',
+        parameters: pathParams({
+          name: 'packageName',
+          example: 'PackageManagement',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = {
     label: 'platform',
diff --git a/services/pub/pub-publisher.service.js b/services/pub/pub-publisher.service.js
index bc22714f13139b98664451ac0f358b3093ad0577..36f01074d2540e56c62aa6fec7a9bb492a145d16 100644
--- a/services/pub/pub-publisher.service.js
+++ b/services/pub/pub-publisher.service.js
@@ -1,5 +1,5 @@
 import Joi from 'joi'
-import { BaseJsonService } from '../index.js'
+import { BaseJsonService, pathParams } from '../index.js'
 
 const schema = Joi.object({
   publisherId: Joi.string().allow(null).required(),
@@ -13,14 +13,17 @@ export class PubPublisher extends BaseJsonService {
     pattern: ':packageName',
   }
 
-  static examples = [
-    {
-      title: 'Pub Publisher',
-      namedParams: { packageName: 'path' },
-      staticPreview: this.render({ publisher: 'dart.dev' }),
-      keywords: ['dart', 'dartlang'],
+  static openApi = {
+    '/pub/publisher/{packageName}': {
+      get: {
+        summary: 'Pub Publisher',
+        parameters: pathParams({
+          name: 'packageName',
+          example: 'path',
+        }),
+      },
     },
-  ]
+  }
 
   static _cacheLength = 3600
 
diff --git a/services/pypi/pypi-format.service.js b/services/pypi/pypi-format.service.js
index cef3285e4843344f41b128620bc02fdfc00c8afe..e1d02bc9fe21ab99b5f5024f7a1ac868be624625 100644
--- a/services/pypi/pypi-format.service.js
+++ b/services/pypi/pypi-format.service.js
@@ -1,3 +1,4 @@
+import { pathParams } from '../index.js'
 import PypiBase from './pypi-base.js'
 import { getPackageFormats } from './pypi-helpers.js'
 
@@ -6,15 +7,17 @@ export default class PypiFormat extends PypiBase {
 
   static route = this.buildRoute('pypi/format')
 
-  static examples = [
-    {
-      title: 'PyPI - Format',
-      pattern: ':packageName',
-      namedParams: { packageName: 'Django' },
-      staticPreview: this.render({ hasWheel: true }),
-      keywords: ['python'],
+  static openApi = {
+    '/pypi/format/{packageName}': {
+      get: {
+        summary: 'PyPI - Format',
+        parameters: pathParams({
+          name: 'packageName',
+          example: 'Django',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = { label: 'format' }
 
diff --git a/services/pypi/pypi-implementation.service.js b/services/pypi/pypi-implementation.service.js
index bf03542989e032a21c1161150645fb85bdb717ee..8da1079c15223451cb97e583ed0968edee6b60ae 100644
--- a/services/pypi/pypi-implementation.service.js
+++ b/services/pypi/pypi-implementation.service.js
@@ -1,3 +1,4 @@
+import { pathParams } from '../index.js'
 import PypiBase from './pypi-base.js'
 import { parseClassifiers } from './pypi-helpers.js'
 
@@ -6,15 +7,17 @@ export default class PypiImplementation extends PypiBase {
 
   static route = this.buildRoute('pypi/implementation')
 
-  static examples = [
-    {
-      title: 'PyPI - Implementation',
-      pattern: ':packageName',
-      namedParams: { packageName: 'Django' },
-      staticPreview: this.render({ implementations: ['cpython'] }),
-      keywords: ['python'],
+  static openApi = {
+    '/pypi/implementation/{packageName}': {
+      get: {
+        summary: 'PyPI - Implementation',
+        parameters: pathParams({
+          name: 'packageName',
+          example: 'Django',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = { label: 'implementation' }
 
diff --git a/services/pypi/pypi-license.service.js b/services/pypi/pypi-license.service.js
index c2d2a3228cf0a9fcb9da758c641de1bd0a6ba663..4bb89dc498cfb1019a501105507c4894f98309ab 100644
--- a/services/pypi/pypi-license.service.js
+++ b/services/pypi/pypi-license.service.js
@@ -1,3 +1,4 @@
+import { pathParams } from '../index.js'
 import { renderLicenseBadge } from '../licenses.js'
 import PypiBase from './pypi-base.js'
 import { getLicenses } from './pypi-helpers.js'
@@ -7,15 +8,17 @@ export default class PypiLicense extends PypiBase {
 
   static route = this.buildRoute('pypi/l')
 
-  static examples = [
-    {
-      title: 'PyPI - License',
-      pattern: ':packageName',
-      namedParams: { packageName: 'Django' },
-      staticPreview: this.render({ licenses: ['BSD'] }),
-      keywords: ['python'],
+  static openApi = {
+    '/pypi/l/{packageName}': {
+      get: {
+        summary: 'PyPI - License',
+        parameters: pathParams({
+          name: 'packageName',
+          example: 'Django',
+        }),
+      },
     },
-  ]
+  }
 
   static render({ licenses }) {
     return renderLicenseBadge({ licenses })
diff --git a/services/pypi/pypi-python-versions.service.js b/services/pypi/pypi-python-versions.service.js
index 58651ab3d3a134b9b19958fbbceccf7852a092c4..49db5cb050bc7625e795d70a36a90619b8041a08 100644
--- a/services/pypi/pypi-python-versions.service.js
+++ b/services/pypi/pypi-python-versions.service.js
@@ -1,4 +1,5 @@
 import semver from 'semver'
+import { pathParams } from '../index.js'
 import PypiBase from './pypi-base.js'
 import { parseClassifiers } from './pypi-helpers.js'
 
@@ -7,14 +8,17 @@ export default class PypiPythonVersions extends PypiBase {
 
   static route = this.buildRoute('pypi/pyversions')
 
-  static examples = [
-    {
-      title: 'PyPI - Python Version',
-      pattern: ':packageName',
-      namedParams: { packageName: 'Django' },
-      staticPreview: this.render({ versions: ['3.5', '3.6', '3.7'] }),
+  static openApi = {
+    '/pypi/pyversions/{packageName}': {
+      get: {
+        summary: 'PyPI - Python Version',
+        parameters: pathParams({
+          name: 'packageName',
+          example: 'Django',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = { label: 'python' }
 
diff --git a/services/pypi/pypi-status.service.js b/services/pypi/pypi-status.service.js
index 41586a90a5680ef8fe6dd0cdd436f50566676d67..12d85e39cc5b391c7fb77ab8c679ac292966c5dd 100644
--- a/services/pypi/pypi-status.service.js
+++ b/services/pypi/pypi-status.service.js
@@ -1,3 +1,4 @@
+import { pathParams } from '../index.js'
 import PypiBase from './pypi-base.js'
 import { parseClassifiers } from './pypi-helpers.js'
 
@@ -6,15 +7,17 @@ export default class PypiStatus extends PypiBase {
 
   static route = this.buildRoute('pypi/status')
 
-  static examples = [
-    {
-      title: 'PyPI - Status',
-      pattern: ':packageName',
-      namedParams: { packageName: 'Django' },
-      staticPreview: this.render({ status: 'stable' }),
-      keywords: ['python'],
+  static openApi = {
+    '/pypi/status/{packageName}': {
+      get: {
+        summary: 'PyPI - Status',
+        parameters: pathParams({
+          name: 'packageName',
+          example: 'Django',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = { label: 'status' }
 
diff --git a/services/pypi/pypi-version.service.js b/services/pypi/pypi-version.service.js
index e5a706f02e58e6add05d37561ec7b1d884720bdf..04e018be975f6551a01caafeb5c2e2f5df972aa8 100644
--- a/services/pypi/pypi-version.service.js
+++ b/services/pypi/pypi-version.service.js
@@ -1,3 +1,4 @@
+import { pathParams } from '../index.js'
 import { pep440VersionColor } from '../color-formatters.js'
 import { renderVersionBadge } from '../version.js'
 import PypiBase from './pypi-base.js'
@@ -7,15 +8,17 @@ export default class PypiVersion extends PypiBase {
 
   static route = this.buildRoute('pypi/v')
 
-  static examples = [
-    {
-      title: 'PyPI',
-      pattern: ':packageName',
-      namedParams: { packageName: 'nine' },
-      staticPreview: this.render({ version: '1.0.0' }),
-      keywords: ['python'],
+  static openApi = {
+    '/pypi/v/{packageName}': {
+      get: {
+        summary: 'PyPI - Version',
+        parameters: pathParams({
+          name: 'packageName',
+          example: 'nine',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = { label: 'pypi' }
 
diff --git a/services/pypi/pypi-wheel.service.js b/services/pypi/pypi-wheel.service.js
index a81e2e4d42bd59f32678374303cf2596afcca47e..ce151cb0553c1706f08e7a4025a78c02641a478a 100644
--- a/services/pypi/pypi-wheel.service.js
+++ b/services/pypi/pypi-wheel.service.js
@@ -1,3 +1,4 @@
+import { pathParams } from '../index.js'
 import PypiBase from './pypi-base.js'
 import { getPackageFormats } from './pypi-helpers.js'
 
@@ -6,15 +7,17 @@ export default class PypiWheel extends PypiBase {
 
   static route = this.buildRoute('pypi/wheel')
 
-  static examples = [
-    {
-      title: 'PyPI - Wheel',
-      pattern: ':packageName',
-      namedParams: { packageName: 'Django' },
-      staticPreview: this.render({ hasWheel: true }),
-      keywords: ['python'],
+  static openApi = {
+    '/pypi/wheel/{packageName}': {
+      get: {
+        summary: 'PyPI - Wheel',
+        parameters: pathParams({
+          name: 'packageName',
+          example: 'Django',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = { label: 'wheel' }
 
diff --git a/services/reddit/subreddit-subscribers.service.js b/services/reddit/subreddit-subscribers.service.js
index 0f908075690b6f1efe907e7d27013f2e7cf78e87..a0d00483c7fd6adb9297dba2900905d48ca3093f 100644
--- a/services/reddit/subreddit-subscribers.service.js
+++ b/services/reddit/subreddit-subscribers.service.js
@@ -1,7 +1,7 @@
 import Joi from 'joi'
 import { optionalNonNegativeInteger } from '../validators.js'
 import { metric } from '../text-formatters.js'
-import { BaseJsonService, NotFound } from '../index.js'
+import { BaseJsonService, NotFound, pathParams } from '../index.js'
 
 const schema = Joi.object({
   data: Joi.object({
@@ -17,18 +17,17 @@ export default class RedditSubredditSubscribers extends BaseJsonService {
     pattern: ':subreddit',
   }
 
-  static examples = [
-    {
-      title: 'Subreddit subscribers',
-      namedParams: { subreddit: 'drums' },
-      staticPreview: {
-        label: 'follow r/drums',
-        message: '77k',
-        color: 'red',
-        style: 'social',
+  static openApi = {
+    '/reddit/subreddit-subscribers/{subreddit}': {
+      get: {
+        summary: 'Subreddit subscribers',
+        parameters: pathParams({
+          name: 'subreddit',
+          example: 'drums',
+        }),
       },
     },
-  ]
+  }
 
   static _cacheLength = 7200
 
diff --git a/services/repology/repology-repositories.service.js b/services/repology/repology-repositories.service.js
index 98b5e3ff55dc6c6e6457a380823685a3959d85ee..bd89fc5ef15a6e5144253ad96eff660af6b4bfed 100644
--- a/services/repology/repology-repositories.service.js
+++ b/services/repology/repology-repositories.service.js
@@ -1,7 +1,7 @@
 import Joi from 'joi'
 import { metric } from '../text-formatters.js'
 import { nonNegativeInteger } from '../validators.js'
-import { BaseSvgScrapingService } from '../index.js'
+import { BaseSvgScrapingService, pathParams } from '../index.js'
 
 const schema = Joi.object({
   message: nonNegativeInteger,
@@ -15,13 +15,17 @@ export default class RepologyRepositories extends BaseSvgScrapingService {
     pattern: ':projectName',
   }
 
-  static examples = [
-    {
-      title: 'Repology - Repositories',
-      namedParams: { projectName: 'starship' },
-      staticPreview: this.render({ repositoryCount: '18' }),
+  static openApi = {
+    '/repology/repositories/{projectName}': {
+      get: {
+        summary: 'Repology - Repositories',
+        parameters: pathParams({
+          name: 'projectName',
+          example: 'starship',
+        }),
+      },
     },
-  ]
+  }
 
   static defaultBadgeData = {
     label: 'repositories',