Skip to main content

Webhook Signatures

Webhook signatures let your receiver verify messages from Files.com before acting on their contents, such as downloading a file or starting a downstream job. Use X-Files-Signature-V2 for all new and existing folder webhook integrations, including EV1 and EV2.

Files.com introduced V2 because MD5, used by the older folder webhook signatures, is no longer considered secure. V2 replaces those methods with HMAC-SHA256 and verifies the complete POST body or GET query string. Existing receivers should move to V2; the older methods remain available for backward compatibility.

For a folder webhook, the shared secret is the Verification token in Advanced Settings. The field is populated with a unique random token that you can remove or regenerate. A nonblank token enables signing; a blank token disables it. Configure your receiver with the same token and keep it private. Changing or regenerating the token requires updating the receiver to match. Moving to V2 does not itself require a new token.

Signed Request Bytes

The X-Files-Signature-V2 header contains the HMAC-SHA256 digest as exactly 64 lowercase hexadecimal characters, with no sha256= prefix. Use the configured secret as the HMAC key and select the message bytes according to the request method.

For POST, verify the exact received body bytes before parsing them. This includes JSON, XML, URL-encoded forms, the complete multipart body including its boundaries, and file contents sent as the body. EV1 and EV2 use their exact JSON body bytes. Do not decode binary data as text, extract only a multipart file or field, or parse and reserialize a body for verification. Changes to whitespace, key order, escaping, or boundaries change the signed bytes even when the resulting data looks the same.

For GET folder webhooks, verify the entire raw query string, excluding the leading ?. Include parameters already present in the destination URL as well as those added by Files.com. Preserve parameter order, duplicate parameters, and percent encoding; do not decode, sort, or rebuild the query. For example, a received query of route=orders&tag=a+b&tag=a%20b&path=incoming%2Forder.csv must be verified exactly as written. Different destination URLs can produce different signatures for the same file action.

Receiver Verification Example

Require a valid V2 signature and compare it using your language's constant-time comparison function. A missing, malformed, or incorrect V2 signature must stop processing. Do not accept the request by falling back to an older signature header.

This Python example accepts a Flask request and the configured secret as a string. It uses Flask's raw query and body accessExternal LinkThis link leads to an external website and will open in a new tab and Python's constant-time comparisonExternal LinkThis link leads to an external website and will open in a new tab. Call it before reading request.json, request.form, or request.files. Configure any middleware or proxy in front of the receiver to preserve the original body and query bytes.

import hashlib
import hmac
import re


def verify_files_webhook(request, secret):
    signature = request.headers.get("X-Files-Signature-V2", "")
    if not secret or re.fullmatch(r"[0-9a-f]{64}", signature) is None:
        return False

    if request.method == "GET":
        message = request.query_string  # Raw bytes after "?".
    elif request.method == "POST":
        message = request.get_data(cache=True, as_text=False)
    else:
        return False

    expected = hmac.new(secret.encode("utf-8"), message, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

If this function returns False, reject the request without processing it. If it returns True, parse the body or query and handle the event.

A valid signature confirms that the signed bytes match the shared secret. It does not establish that a delivery is new or that your application has not already processed it. Account for repeated deliveries separately so a retry does not repeat business work that already succeeded.

You can also restrict incoming connections to the published Files.com IP addresses, or your assigned addresses when the webhook uses Dedicated IPs. This is an additional connection control; it does not replace message verification.

Migration and Deprecated Signatures

To migrate a receiver, keep its existing secret and payload format, then update it to verify the raw request bytes using X-Files-Signature-V2. Once it uses V2, require V2 on every delivery. The older headers and verification methods below are deprecated and remain available for backward compatibility. This deprecation applies to signature verification, not to the EV1 or EV2 payload formats.

The legacy signature reference preserves the exact older rules for maintaining existing folder webhook receivers.

Legacy Signature Reference

Webhook TypeDeprecated HeaderVerification for Compatibility
Folder webhookX-Files-SignatureCalculate the lowercase hexadecimal MD5 digest of the verification token followed by the triggering file path, with no separator and without adding a leading slash. This verifies the path, not the complete message.
EV1 or EV2 folder webhookX-Exavault-SignatureCalculate the lowercase hexadecimal MD5 digest of the verification token followed by the exact raw request body, with no separator. Preserve the body bytes before JSON parsing. Legacy Format Webhooks explains this method.

For an existing receiver that still uses one of these methods, compare the calculated digest with the corresponding header using a constant-time comparison function. These methods are compatibility references, not alternatives to try when V2 verification fails.