Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Generate a shareable badge by treating the webhook as an untrusted event, verifying it, converting it to a small internal achievement record, issuing an Open Badges assertion through an issuer API, and returning a stable verification URL. Process the issuance asynchronously, record the provider delivery ID for idempotency, and deliver the URL (and optionally a preview image) through email, Slack, Discord, or a profile page.

The reliable webhook-to-badge flow

A production implementation has six stages. Keeping them separate lets you change event providers or badge vendors without rewriting your application.

  1. Receive: expose a public HTTPS endpoint and configure the event source to call it.
  2. Verify: validate the provider signature and timestamp against the raw request bytes before trusting any achievement fields.
  3. Normalize: map provider-specific payloads to an internal event such as pull_request_merged, quest_completed, or milestone_reached.
  4. Deduplicate: use the delivery ID (or another provider event ID) as an idempotency key so retries cannot issue a second badge.
  5. Issue: call your badge issuer with recipient, issuer, criteria, evidence, and issue-date metadata. Save the issuer response and its stable verification URL.
  6. Deliver: send the URL or image to the user through the channel they use, while making the verification page the authoritative proof.

GitHub describes webhooks as HTTP requests sent to a URL for subscribed events, including deployments, notifications, and project creation. GitHub deliveries include delivery headers and HMAC signatures, and a payload is capped at 25 MB. Discord describes webhook events as one-way HTTP notifications; its incoming webhooks are channel-specific endpoints that accept posts without a bot or persistent connection. Slack incoming webhooks likewise expose a unique URL that accepts a JSON message payload.

Register endpoints and verify every provider

GitHub

Register an HTTPS webhook on the repository or organization, select only the events you need, and set a long random secret. Verify the X-Hub-Signature-256 HMAC using the raw body and constant-time comparison. Also retain X-GitHub-Delivery as the idempotency key. Reject missing signatures, mismatched signatures, oversized bodies, and timestamps outside the replay window you choose.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Custom Enamel Pins 50-500 Pcs, Design Your Own Personalized Lapel Badge with Your Text, Logo, or Image (Soft Enamel Pins)
  • Custom Design Capability - Upload your artwork, logo, or design to create personalized soft enamel pins. Used for branding, events, and commemorative purposes.
  • Finish & Attachment Variety - Available in gold, silver, and black nickel plating. Backing options include butterfly clutch, rubber clutch, and safety pin styles.
  • Multi-Purpose Functionality - Works as event memorabilia and wearable branding items. Applicable to corporate events, trade shows, conferences, fundraisers, and team activities.
  • Textured Enamel Construction - Soft enamel process creates recessed color areas with a textured finish. Appropriate for personal collections, gift exchanges, and recognition programs.
  • Protective Individual Packaging - Made with metal base and soft enamel fill. Each unit is individually packaged to prevent finish damage during shipping.

Discord

For Discord interactions and signed webhook events, verify X-Signature-Ed25519 over the concatenation of X-Signature-Timestamp and the raw request body with your application public key. Reject stale timestamps before queuing work. A Discord incoming webhook used only for delivery is different: it is an outbound channel URL, so protect it like a password and never expose it in client-side code.

Slack

Slack’s incoming webhook URL is a credential. Store it in a secret manager, restrict who can read it, and rotate it if it appears in logs or source control. If your Slack event source provides signed requests, apply Slack’s documented signature and timestamp check before normalizing the event. Do not assume that a message arriving at your own endpoint is proof that a user earned a badge.

A runnable Node.js reference implementation

The following Express example handles a GitHub pull_request delivery, verifies the signature, acknowledges quickly, and queues an idempotent issuance job. The in-memory map is for demonstration; use a durable database or key-value store in production.

import express from "express";
import crypto from "node:crypto";

const app = express();
const PORT = process.env.PORT || 3000;
const GITHUB_SECRET = process.env.GITHUB_WEBHOOK_SECRET;
const ISSUER_API_URL = process.env.ISSUER_API_URL;
const ISSUER_TOKEN = process.env.ISSUER_TOKEN;
const processed = new Map(); // replace with a durable unique constraint

app.post("/webhooks/github", express.raw({ type: "*/*", limit: "26mb" }), (req, res) => {
  const signature = req.get("x-hub-signature-256") || "";
  const deliveryId = req.get("x-github-delivery");
  if (!deliveryId || !GITHUB_SECRET) return res.sendStatus(400);

  const expected = "sha256=" + crypto
    .createHmac("sha256", GITHUB_SECRET)
    .update(req.body)
    .digest("hex");
  const valid = signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  if (!valid) return res.sendStatus(401);

  let event;
  try { event = JSON.parse(req.body.toString("utf8")); }
  catch { return res.sendStatus(400); }

  if (processed.has(deliveryId)) return res.sendStatus(202);
  processed.set(deliveryId, { state: "queued", receivedAt: new Date().toISOString() });

  // Acknowledge before making a slow issuer request.
  res.sendStatus(202);
  queueMicrotask(() => processAchievement(deliveryId, event).catch((err) => {
    processed.set(deliveryId, { state: "failed", error: String(err) });
    console.error("badge issuance failed", deliveryId, err);
  }));
});

async function processAchievement(deliveryId, payload) {
  const action = payload.action;
  const pr = payload.pull_request;
  if (action !== "closed" || !pr?.merged || !pr.user?.login) return;

  const achievement = {
    type: "pull_request_merged",
    recipient: { id: pr.user.login, source: "github" },
    occurredAt: payload.pull_request.merged_at || new Date().toISOString(),
    evidence: {
      url: pr.html_url,
      eventId: deliveryId,
      repository: payload.repository?.full_name
    }
  };

  const response = await fetch(ISSUER_API_URL, {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "authorization": `Bearer ${ISSUER_TOKEN}`,
      "idempotency-key": deliveryId
    },
    body: JSON.stringify({
      achievement,
      badge: {
        name: "Merged pull request",
        criteria: "A pull request was reviewed and merged.",
        issuer: { id: "https://your.example/issuers/engineering" }
      }
    })
  });
  if (!response.ok) throw new Error(`issuer returned ${response.status}`);
  const issued = await response.json();
  processed.set(deliveryId, {
    state: "issued",
    verificationUrl: issued.verificationUrl,
    issuerResponse: issued
  });
  await deliverToUser(achievement.recipient, issued.verificationUrl);
}

async function deliverToUser(recipient, verificationUrl) {
  // Implement email, Slack, Discord, or profile notification here.
  console.log(`Send ${verificationUrl} to ${recipient.source}:${recipient.id}`);
}

app.listen(PORT, () => console.log(`listening on ${PORT}`));

This example deliberately treats the issuer URL and response shape as configuration. Credly’s Web Service API is a JSON-over-SSL REST service using token or OAuth authentication; other issuers use different paths and field names. Map the normalized object to the exact API version you select, and persist the complete response for audit and replay.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Custom Personalized Lapel Pin Logo Name Enamel Collar Brooch Badge Gift
  • Fully Customizable DesignSupport personalized logo, school emblem, text, monogram and size. Available in classic gold, silver and black finishes, perfectly present your brand identity and exclusive style.
  • Premium Stainless Steel MaterialMade of high‑quality stainless steel with handcrafted relief & polished finish, sturdy, wear‑resistant, no fading, comfortable to wear and long‑lasting for daily use.
  • Wide Application ScenariosIdeal for corporate branding, employee recognition, school uniforms, team identity, conferences, anniversaries and commemorative events, suitable for suits, bags, hats and uniforms.
  • Elegant & Professional AppearanceExquisite relief craft with smooth surface and bright luster, elevate your business look and add a sense of honor and formality to any outfit.
  • Perfect Gift & Promotion ChoiceReady as business gifts, corporate souvenirs, promotional giveaways and commemorative keepsakes, help enhance brand awareness and team cohesion.

Design the achievement and verification record

Include evidence that a verifier can inspect

At minimum, retain the recipient identifier, issuer identity, badge name, criteria, issue date, source event ID, and evidence URL. Avoid putting secrets or private payload fields in public metadata. If the source URL requires authentication, publish a redacted evidence page under your control instead.

Use the verification page as the trust signal

A badge image is presentation. The verification URL and signed or issuer-hosted metadata carry the meaning. Credly describes a badge as a digital representation of a learning outcome, experience, or competency; its metadata supplies context and verification and can be shared on LinkedIn, Facebook, Twitter, email, or an embedded website. Make your share page readable without JavaScript, include issuer and criteria text, and expose machine-readable metadata supported by your chosen Open Badges version.

Choose a portability target

Open Badges 2.0 and 3.0 have different schemas and ecosystem expectations. Confirm which version your issuer emits, which recipient wallets accept it, and whether exported assertions remain verifiable after your subscription ends. Do not label a proprietary image as an Open Badge unless it includes the required assertion and verification data.

Pick an issuer and delivery model

Option Control Automation and verification Best fit
Credly Hosted program; authentication through token or OAuth. Web Service API uses JSON and SSL; Credly also documents webhooks for tracking program events and changes. Sharing destinations include social networks, email, and embedded websites. Organizations that want a managed issuing and sharing platform.
Badgr Server Self-hosted control over deployment and data. Issuer API plus standards-compliant public JSON endpoints for Issuer, BadgeClass, and Assertion. It also provides image redirects and social-preview-friendly routes. Teams that need infrastructure and data control.
openbadges.me Hosted service with configurable event rules. Its Events Service records events, applies custom rules, and triggers outcomes such as issuing a badge. Programs that prefer rule configuration over maintaining a worker.

Pricing, quotas, retention, Open Badges version support, and partner terms vary and are not uniform across these options. Check the current contract and API documentation before committing. If you self-host, budget for database backups, key rotation, public HTTPS, monitoring, and abuse controls in addition to compute.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Custom Enamel Pins, Personalized Lapel Pin Badges, Custom Logo Pins (2")
  • 【Personalized Your Own Design】 Create your own custom soft enamel pins with your logo, artwork, text, name, image, or other personalized designs. Perfect for turning your brand identity, event theme, team logo, or creative artwork into unique custom enamel pins for promotion, recognition, gifts, and personal use.
  • 【Premium Soft Enamel Craftsmanship】 Made with durable metal and colorful soft enamel, these personalized pins feature raised metal outlines that add definition and a classic textured look. The vibrant enamel colors highlight your custom artwork while providing a lightweight and durable accessory for everyday wear, collecting, or special events.
  • 【Multiple Plating & Backing Options】 Choose from a variety of plating colors, including gold, silver, black nickel, and other finishes to complement your custom design. Different backing options are also available, such as butterfly clutch, rubber clutch, and safety clutch, allowing you to select the attachment that best fits your needs.
  • 【Versatile for Business, Events & Everyday Use】 These personalized enamel pins are ideal for company branding, employee recognition, school activities, clubs, sports teams, fundraisers, conferences, trade shows, weddings, parties, and promotional events. Add them to jackets, backpacks, hats, bags, lanyards, or uniforms for a memorable custom touch.
  • 【Great for Gifts, Collectors & Bulk Orders】 Custom soft enamel pins make thoughtful gifts and collectible keepsakes for customers, employees, team members, friends, and family. Ideal for bulk orders, promotional giveaways, event favors, membership badges, and commemorative gifts, with professional customization support to help bring your design to life.

Make retries and concurrency safe

  • Create a unique database constraint on (provider, delivery_id) and insert the event before enqueueing it.
  • Store states such as received, processing, issued, delivered, and failed, with timestamps and error text.
  • Pass a stable idempotency key to the issuer when supported. If it is not supported, lock the event row while issuing and treat a timed-out request as unknown until you reconcile it.
  • Use exponential backoff with a maximum attempt count. Do not retry signature failures or malformed payloads.
  • Acknowledge the webhook quickly (normally with a 2xx response) and perform issuer calls in a worker. Long synchronous requests cause providers to retry and can create duplicate work.
  • Keep the raw payload encrypted or access-controlled for the shortest retention period that meets your audit needs.

For bulk milestones, separate event ingestion from notification fan-out. One worker can issue the assertion; another can send Slack, Discord, and email messages. This prevents a slow chat API from blocking issuance.

Deliver the badge without leaking credentials

Slack

Post a concise message containing the recipient’s display name, badge title, and verification URL to the unique incoming webhook URL. Keep the URL server-side and redact it from logs. If the badge is private, send a short-lived authenticated application link rather than a public assertion.

Discord

Use a channel-specific incoming webhook for announcements, or send a direct message through your bot when the recipient must be identified privately. The message should point to the verification page; an attached image is optional.

Email and profile pages

Send the stable URL in plain text and HTML email, and render the same URL from the user’s profile. Include an accessible text alternative for any badge image. If users can revoke or hide badges, make the verification response reflect that state instead of leaving an apparently valid cached image.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Custom Personalized Lapel Pin Logo Name Enamel Metal Brooch Badge Gift
  • Custom Design: Create personalized lapel pins featuring your company logo, brand name, or custom text in elegant gold, silver, or black finishes
  • Premium Material: Crafted from high-quality stainless steel ensuring durability and a professional appearance for long-lasting use
  • Versatile Usage: Perfect for corporate branding, school badges, organizational emblems, business gifts, and special event souvenirs
  • Professional Look: Enamel finish provides a sophisticated and polished appearance suitable for business attire and formal occasions
  • Multiple Options: Available in various metallic finishes including gold, silver, and black to match your branding requirements
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting checklist

Every request returns 401

Log the header names (not secrets), confirm that the framework did not parse and re-serialize the body before HMAC verification, and verify the secret belongs to the exact webhook configuration. GitHub requires X-Hub-Signature-256; Discord’s signed events require both signature and timestamp headers.

Badges are duplicated

The provider is retrying, multiple subscriptions are active, or the idempotency record is written after issuance. Insert the delivery ID before queueing, enforce a unique constraint, and reconcile issuer responses after network timeouts.

The issuer rejects the payload

Compare your field names and Open Badges version with the issuer’s current schema. Check recipient format, issuer authorization, required criteria or evidence fields, and whether the assertion is allowed to reference a private URL.

The webhook times out

Return a success response after validation and enqueue the event. Move image generation, issuer calls, and Slack or Discord delivery to workers. Monitor queue age and retry counts instead of extending the HTTP timeout.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
10PCS Custom Lapel Pin, Personalized Brooch Pins with Logo/Name/Text Enamel Brooch Pins,Gold/Silver/RoseGold/Black Business Badge for Company Business Wedding School Souvenir Gifts Party (1.5")
  • 【Design Your Own Custom Lapel Pin】Create a unique custom pin with your logo, company name, initials, artwork, or custom text. Simply click "Customize Now" to upload your design and personalize a professional custom lapel pin for branding, recognition, or memorable keepsakes. Available in multiple sizes and finishes to match your style.
  • 【Premium Zinc Alloy & Lasting Quality】Crafted from durable premium zinc alloy, our personalized pin features precision die-casting, crisp details, and a smooth polished finish for a premium look. Rust-resistant, fade-resistant, and built for everyday wear, these custom metal pins are lightweight yet sturdy, making them perfect for suits, jackets, uniforms, hats, backpacks, and bags.
  • 【Perfect for Business & Special Events】Whether you need logo pins for your company, name pins for employees, or custom accessories for schools, clubs, military units, trade shows, graduations, conferences, weddings, and team events, these custom badges help showcase your identity with a clean, professional appearance.
  • 【Meaningful Personalized Gift】Our customized brooch makes a thoughtful gift for coworkers, business partners, friends, teachers, graduates, fathers, husbands, or team members. Ideal for birthdays, Father's Day, anniversaries, Christmas, employee appreciation, corporate recognition, promotional giveaways, and commemorative occasions.
  • 【Easy Customization & Dedicated Support】Upload your logo, photo, or text, and our experienced designers will prepare your custom design with attention to every detail. We are committed to delivering high-quality custom metal pins with reliable craftsmanship and responsive customer support, ensuring your order meets your expectations from design to delivery.

A shared image looks correct but cannot be verified

Test the verification URL in a private browser and with a machine-readable request. Ensure the page still resolves after cache expiry, the issuer identity is present, and the assertion has not been revoked or replaced.

Performance, privacy, and operating costs

  • Latency: webhook acknowledgment should not wait for badge issuance or chat delivery. Measure time from receipt to a stable verification URL separately from notification latency.
  • Reliability: monitor signature failures, unknown event types, queue depth, issuer status codes, duplicate suppression, and delivery failures. Alert on a rise in failed issuance rather than on normal provider retries.
  • Security: rotate webhook secrets and outgoing webhook URLs, limit egress to approved issuer hosts, encrypt recipient data, and remove personal fields from public evidence.
  • Cost: compare issuer charges, storage, worker execution, outbound email, and chat delivery. No comparable prices for Credly, Badgr Server, or openbadges.me are established here, so obtain current quotes and quota details.
  • Change management: pin SDK and API versions where possible, retain a sample payload for each provider, and test signature verification and replay handling whenever you change your HTTP framework.

Or skip the browser setup

If you need a clean preview image of the verification page for a profile, email, or chat message, ScreenshotNeo can capture it through one GET request. It accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.

Use the verification URL you saved from the issuer as the target. Full options and parameter names are in the ScreenshotNeo documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/badges/123 -o badge.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/badges/123"}, timeout=90)
open("badge.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/badges/123' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Every feature is included on every plan. The Free plan provides 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to generate the preview without maintaining browser automation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Launch checklist

  • HTTPS endpoint registered with the smallest practical event subscription.
  • Raw-body signature and timestamp verification implemented before JSON parsing.
  • Provider delivery ID stored under a durable unique constraint.
  • Internal event schema documented and versioned.
  • Issuer mapping tested for recipient, issuer, criteria, evidence, date, and Open Badges version.
  • Asynchronous worker with bounded retries and reconciliation for timeouts.
  • Stable verification URL saved before notification fan-out.
  • Public metadata reviewed for personal-data leakage and revocation behavior.
  • Slack, Discord, and email credentials stored outside source control.
  • Monitoring covers rejected signatures, duplicate events, issuer errors, and undelivered notifications.

Frequently Asked Questions

Can I award a badge from more than one webhook provider?

Yes. Keep provider adapters separate and map each payload into the same internal achievement event. The issuer and idempotency layers can then remain provider-neutral.

Should I store the original webhook payload forever?

Usually not. Retain it only as long as your audit and dispute process requires, encrypt it, restrict access, and store a minimized normalized event for routine operations.

Is a PNG or JPEG badge image itself verifiable?

No. Treat the image as a visual representation. Verification depends on the issuer metadata and stable verification URL linked from the share page.

What happens if a user earns the same badge twice?

Decide whether the program issues a new assertion for each qualifying event or keeps one assertion and updates evidence. Encode that policy in your idempotency key and database constraints.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.