HTTP Signature

Some partners want every request signed. The signature proves two things: that the request came from you, and that nobody changed it on the way. They compute the same signature on their side and compare.

PalDock does the signing. You choose a preset that matches what the partner’s documentation describes, and PalDock builds the signature from the request as it is being sent.

Presets are fixed and you cannot write your own signing rule. If a partner needs one we do not have yet, tell us and we will add it.

The settings

  • Preset decides what gets signed and how.
  • Hash is SHA-256 or SHA-512. The partner will say which. MD5 presets do not have this choice.
  • Delimiter is the character used to join values before hashing, either |, & or .. Only presets that join values need it, and the partner’s example will show you which one they use.
  • Position decides whether your secret goes before the data or after it. Prefix puts it first, suffix puts it last. MD5 presets need this, and the partner’s example is the only way to tell which they expect.

Secrets

Store the signing credentials as parameters in the integration:

  • sign_secret is the shared secret. Every MD5 and HMAC preset needs it.
  • sign_keyid is the key identifier that goes into the signature header. Only HSIG needs it.

If one is missing when the request runs, the node fails and the log says which.

Where the signature ends up

This is the step people miss, and the failure is silent.

  • MD5 presets add it to the body themselves. A signature field appears in the payload. You do nothing.

Every other preset gives you tags and you place them in the headers yourself:

  • {signature} is the signature
  • {digest} is the digest, where the preset makes one
  • {timestamp_sign} is the timestamp that was signed
  • {random_sign} is the nonce, for the preset that uses one

If the partner asks for the signature in X-Signature, you add that header with {signature} as its value. Forget it and the request goes out unsigned, which the partner usually answers with a bare 401.

When a preset signs a timestamp, PalDock also adds a Timestamp header on its own, so what it signed and what the partner sees are always the same value.

A complete example

The partner’s documentation says: sign the raw JSON body with HMAC SHA-256 and send it in X-Signature.

In the request:

Method:   POST
Endpoint: {endpoint}/leads
Format:   JSON
Body:     first_name  {first_name}
          last_name   {last_name}
          email       {email}

In the headers:

X-Signature: {signature}

In the Signature card:

Preset:    HMAC · Body
Hash:      SHA-256
Delimiter: |

And in the integration parameters:

sign_secret: the key they gave you

That is everything. PalDock builds the body, signs it, and replaces {signature} in the header before the request leaves.

Picking the preset

Look for these phrases in the partner’s documentation:

  • “signature from the request body” is HMAC · Body
  • “HMAC(timestamp + body)” or anything about replay protection is HMAC · Unix Timestamp + Body
  • a date header in HTTP format, like Tue, 11 Aug 2026 10:00:00 GMT, is HMAC · RFC 7231 Date + Body
  • “sign the JSON exactly as sent”, with a timestamp, is HMAC · Unix Timestamp + JSON Body
  • “parameters sorted alphabetically”, or an example with sorted keys, is HMAC · Params A→Z
  • a nonce alongside the timestamp, method and path is HMAC · Params A→Z + Nonce + Body Hash
  • “send a Digest header”, or Digest: SHA-256=…, is Digest · Body (Base64)
  • “HTTP Signatures”, “Authorization: Signature”, “signed headers”, or (request-target) is HSIG + Digest
  • an MD5 example, or a hash of joined values with a secret, is one of the MD5 presets

Other terms worth searching their docs for: canonical string, X-Signature, Base64, nonce, SHA-256, SHA-512.

MD5 presets

These join the body into one string, add your secret, and hash the result with MD5. They differ in how that string is built.

Values takes only the values:

value1|value2|value3|secret

Key=Value takes the field names too:

first_name=John&last_name=Doe&secret

As-sent keeps the order from the request editor. A→Z sorts by field name first. If the partner’s example shows the fields in alphabetical order, you want A→Z.

Where the secret sits is set separately, with Position. The two examples above both put it at the end, which is the common case, but some partners expect it at the front.

Nested fields are flattened to their dotted names first, so customer.name is signed as customer.name.

The presets:

  • MD5 · Values · As-sent
  • MD5 · Values · A→Z
  • MD5 · Key=Value · As-sent
  • MD5 · Key=Value · A→Z

HMAC presets

These sign with your secret, which is what makes them stronger than a plain hash. They differ in what exactly they sign.

  • HMAC · Body signs the body values joined with the delimiter.
  • HMAC · Unix Timestamp + Body puts a Unix timestamp in front, so an intercepted request cannot be replayed later.
  • HMAC · RFC 7231 Date + Body is the same, with the timestamp written as an HTTP date.
  • HMAC · Unix Timestamp + JSON Body signs the timestamp followed by the body as JSON, rather than joined values. Use it when the partner signs the exact JSON they receive.
  • HMAC · Params A→Z sorts the body fields by name and signs them as key=value pairs. Note that this covers the body, not the query.
  • HMAC · Params A→Z + Nonce + Body Hash builds a canonical string from the timestamp, a nonce, the method, the path, the sorted query and a hash of the body, then signs that. Use it when the partner asks for a nonce.

Digest

  • Digest · Body (Base64) hashes the body and Base64 encodes it, which is what goes into a Digest header. It needs no secret, because it only proves the body is intact, not who sent it. Partners usually ask for it alongside another signature rather than on its own.

HSIG

  • HSIG + Digest (Base64) · SH (TS,H,RT,DIG) NL LC · HMAC is the full HTTP Signatures scheme.

PalDock builds a canonical string from four lines, in this order: the request target, the host, the digest and the timestamp. It signs that string and produces a complete header including your key id and the algorithm, ready to place with {signature}.

When the request has no body there is no digest, so that line is left out and only the other three are signed. This preset needs both sign_secret and sign_keyid.

When it does not work

  • The tag is missing. The signature was calculated and thrown away. Check the headers first.
  • Body signing is byte sensitive. Whitespace, JSON formatting and field order all change the result. If the partner rebuilds the body their own way before checking, the signature will never match, however correct your preset is. This is the hardest one to spot, and the only way through it is to compare the exact bytes with them.
  • The wrong delimiter. The signature is computed, sent, and rejected. There is nothing in the response to tell you it was the delimiter, so if everything else matches their documentation, try the others.
  • The wrong position. Same story. The secret at the front instead of the back gives a completely different hash, and the rejection looks identical either way.
  • The wrong scope. Check whether they sign the body only, or the query as well. Most presets here sign the body.
  • No body. Most presets need one and the node fails without it.

Insights that
helps you grow

  • Release notes 2026/08/14
    This was a big one. We went through roughly 200 pages of our knowledge base and rewrote the whole thing. Clearer structure, consistent terminology, and…
  • Release notes 2026/07/31
    What’s new in PalDock? A lot of this month went into things you won’t see directly – query optimisation, indexing, and general tuning under the…
  • Free Affiliate tracking software
    Many companies (inlcuding YOU) search for free affiliate tracking software because they want to launch an affiliate program without committing to expensive monthly fees. The…