Gareth Wilson Gareth Wilson

Guide to CloudSignal Webhooks: Features and Best Practices

Published


CloudSignal webhooks notify your application about print-fulfilment activity: an order is validated, an item is produced, packed, shipped, or errors out. If you're building on Cloudprinter.com, CloudSignal is how you react to order and item status changes without polling.

This guide covers how CloudSignal webhooks work, the events you'll handle, how it authenticates (a body field, not a signature), and the best practices for production.

This covers CloudSignal, Cloudprinter.com's outbound webhook product. It is not the unrelated cloudsignal.io MQTT platform.

What are CloudSignal webhooks?

CloudSignal webhooks are JSON POSTs delivered to a URL you configure. Authentication is not an HMAC signature and not Standard Webhooks: each POST carries a plaintext apikey field in the JSON body (a per-endpoint Webhook API key, distinct from your account API key). The receiver checks that value. There's no signature header, no timestamp, and no HMAC, so verification is a body-field match.

CloudSignal webhook features

FeatureDetails
ConfigurationRegister an endpoint with a per-endpoint Webhook API key
AuthenticationPlaintext apikey field in the JSON body (not a signature)
AcknowledgementReturn HTTP 200 or 204
RetriesUp to 100 times over 7 days until a 200/204
Payloadtype, order, item, order_reference, item_reference, datetime, plus type-specific fields
EventsPascalCase, case-sensitive
SDK@cloudprinter/cloudsignal (npm); no pip

Common events

CloudSignal event type values are PascalCase and case-sensitive:

EventFires when
CloudprinterOrderValidatedAn order is validated
ItemValidatedAn item is validated
ItemProduceAn item enters production
ItemProducedAn item is produced
ItemPackedAn item is packed
ItemShippedAn item ships (includes tracking / shipping_option)
ItemErrorAn item errors (includes cause)
ItemCanceledAn item is canceled (includes cause)
CloudprinterOrderCanceledAn order is canceled

Branch on the exact PascalCase type, and read the type-specific fields (for example tracking on ItemShipped).

Setting up CloudSignal webhooks

Register your endpoint and note the per-endpoint Webhook API key CloudSignal issues, this is the value that arrives in each payload's apikey field, and it's distinct from your account API key. Return HTTP 200 or 204 to acknowledge, otherwise CloudSignal retries.

Securing CloudSignal webhooks

There's no signature to verify. Instead, compare the payload's apikey field against the per-endpoint Webhook API key you registered, using a constant-time comparison. Because the key travels in the body, always serve the endpoint over HTTPS and treat the key as a secret.

const crypto = require("crypto");

const WEBHOOK_API_KEY = process.env.CLOUDSIGNAL_WEBHOOK_API_KEY;

function verify(body) {
  // Auth is a plaintext apikey field in the body, not a signature. Constant-time compare.
  const a = Buffer.from(body.apikey || "");
  const b = Buffer.from(WEBHOOK_API_KEY);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

app.post("/webhook", express.json(), (req, res) => {
  if (!verify(req.body)) return res.sendStatus(401);

  res.sendStatus(200); // 200 or 204 to acknowledge, else CloudSignal retries
  processQueue.add(req.body); // branch on type, async
});

The same check in Python:

import hmac
import os

WEBHOOK_API_KEY = os.environ["CLOUDSIGNAL_WEBHOOK_API_KEY"]


def verify(body: dict) -> bool:
    # Constant-time compare of the body's apikey against the per-endpoint key
    return hmac.compare_digest(body.get("apikey", ""), WEBHOOK_API_KEY)

CloudSignal webhook limitations and pain points

Authentication is a body field, not a signature

The Problem: There's no signature header. Authenticity rests on a plaintext apikey in the body, so anyone who learns the key and your URL can post valid-looking events, and the payload can't be cryptographically verified.

Why It Happens: CloudSignal uses a shared per-endpoint key carried in the body.

Workarounds:

  • Serve the endpoint over HTTPS only, treat the key as a secret, rotate it if exposed, and compare it in constant time.

How Hookdeck Can Help: Hookdeck can terminate and check the request at the edge, add its own controls, and give you a managed endpoint in front of your app.

It's CloudSignal, not cloudsignal.io

The Problem: Two unrelated products share the name. cloudsignal.io is an MQTT platform with no outbound webhooks; applying its model here fails.

Why It Happens: The name collides.

Workarounds:

  • Confirm you're integrating Cloudprinter.com's CloudSignal, with the body apikey scheme.

How Hookdeck Can Help: Hookdeck verifies each source with its own scheme, so a name collision doesn't lead to the wrong integration.

The key travels in the body

The Problem: Because the apikey is in the payload, it can end up in logs, traces, and stored events, widening its exposure.

Why It Happens: The credential is part of the message.

Workarounds:

  • Redact apikey from logs and stored payloads, and rotate the key on any suspected exposure.

How Hookdeck Can Help: Hookdeck can handle the credential check centrally, so it isn't spread across every consumer's logs.

Long retry window

The Problem: CloudSignal retries up to 100 times over 7 days until a 200/204, so a flaky endpoint can receive the same event many times.

Why It Happens: CloudSignal persists retries for a week.

Workarounds:

  • Return 200/204 promptly, and dedupe on item_reference / order_reference so repeats are safe.

How Hookdeck Can Help: Hookdeck deduplicates deliveries at the edge, so a week of retries doesn't double-process. See our guide to webhook idempotency.

Best practices

Compare the body apikey in constant time

Match the payload's apikey against the per-endpoint Webhook API key with a constant-time comparison, and keep the endpoint HTTPS-only.

Redact and rotate the key

Keep apikey out of logs and stored payloads, and rotate it if exposed.

Branch on the exact PascalCase type

Handle ItemShipped, ItemError, and the rest by their exact case-sensitive type.

Return 200/204 and process asynchronously

Acknowledge quickly and defer work to a queue. See why to process webhooks asynchronously.

Make CloudSignal webhooks production-ready

Hookdeck fronts your endpoint, deduplicates, and durably queues every order and item event

Conclusion

CloudSignal (Cloudprinter.com) webhooks authenticate with a plaintext apikey field in the JSON body, a per-endpoint Webhook API key, not an HMAC signature. Compare it in constant time, keep the endpoint HTTPS-only, redact and rotate the key, branch on the exact PascalCase type, and dedupe across the 100-retry, 7-day window.

Hookdeck fronts your endpoint, deduplicates, and durably queues every event at the edge, so your app only ever processes verified, unique events.

Get started with Hookdeck for free and handle CloudSignal webhooks reliably in minutes.


Gareth Wilson

Gareth Wilson

Product Marketing

Multi-time founding marketer, Gareth is PMM at Hookdeck and author of the newsletter, Community Inc.