Skip to content

Webhook Event Reference

This page is a detailed reference for GolemDrive’s webhook system. For a general overview of setting up and managing webhooks, see the Webhooks page first.

Every webhook delivery includes an event field that tells you what happened. Here’s the full list of event types you can subscribe to:

EventWhen it fires
file.uploadedA file finishes uploading
file.downloadedA file is downloaded
file.deletedA file is deleted
file.movedA file is moved to a different folder
file.renamedA file is renamed
share.createdA new share link is created
share.accessedSomeone opens a share link
share.downloadedSomeone downloads a file through a share link
share.revokedA share link is disabled or deleted
team.member_joinedA new member joins a team
team.member_leftA member leaves a team
webhook.testTest event sent from the dashboard (contains sample data)

You can subscribe to any combination of these events when creating or updating a webhook.

Every webhook delivery is an HTTP POST request with a JSON body. The top-level structure is always the same:

{
"event": "file.uploaded",
"timestamp": "2026-03-26T14:30:00Z",
"data": {
"file_id": "abc123",
"file_name": "report.pdf",
"folder_id": "def456",
"size_bytes": 2048576
},
"webhook_id": "wh_789",
"delivery_id": "del_012"
}
FieldTypeDescription
eventstringThe event type (e.g., file.uploaded)
timestampstringISO 8601 timestamp of when the event occurred
dataobjectEvent-specific payload (varies by event type)
webhook_idstringThe ID of the webhook configuration that triggered this delivery
delivery_idstringA unique ID for this specific delivery attempt (use for deduplication)

The data field contains different information depending on the event type. See the sections below for examples of each.

file.uploaded

{
"file_id": "abc123",
"file_name": "report.pdf",
"folder_id": "def456",
"size_bytes": 2048576
}

file.downloaded

{
"file_id": "abc123",
"file_name": "report.pdf",
"size_bytes": 2048576
}

file.deleted

{
"file_id": "abc123",
"file_name": "report.pdf"
}

file.moved

{
"file_id": "abc123",
"file_name": "report.pdf",
"from_folder_id": "def456",
"to_folder_id": "ghi789"
}

file.renamed

{
"file_id": "abc123",
"old_name": "report.pdf",
"new_name": "quarterly-report.pdf"
}

share.created

{
"share_id": "sh_abc",
"file_id": "abc123",
"share_url": "https://golemdrive.com/s/xYz123",
"has_password": true,
"expires_at": "2026-04-26T00:00:00Z"
}

share.accessed

{
"share_id": "sh_abc",
"file_id": "abc123",
"accessed_at": "2026-03-26T15:45:00Z"
}

share.downloaded

{
"share_id": "sh_abc",
"file_id": "abc123",
"size_bytes": 2048576
}

share.revoked

{
"share_id": "sh_abc",
"file_id": "abc123",
"revoked_at": "2026-03-26T16:00:00Z"
}

team.member_joined

{
"team_id": "tm_abc",
"team_name": "Engineering",
"user_id": "usr_xyz",
"role": "member"
}

team.member_left

{
"team_id": "tm_abc",
"team_name": "Engineering",
"user_id": "usr_xyz"
}

webhook.test

{
"message": "This is a test event",
"webhook_id": "wh_789"
}

Every webhook delivery includes a signature in the X-GolemDrive-Signature header. You should always verify this signature before processing a webhook to confirm it genuinely came from GolemDrive and wasn’t tampered with.

The signature is an HMAC-SHA256 hash of the raw request body, computed using the webhook secret that was assigned when you created the webhook.

The header format is:

X-GolemDrive-Signature: sha256=a1b2c3d4e5f6...
import hmac
import hashlib
def verify_webhook(payload_body: bytes, signature_header: str, secret: str) -> bool:
expected = hmac.new(
secret.encode("utf-8"),
payload_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature_header)
# Usage in a Flask route:
@app.route("/webhook", methods=["POST"])
def handle_webhook():
signature = request.headers.get("X-GolemDrive-Signature", "")
if not verify_webhook(request.data, signature, WEBHOOK_SECRET):
return "Invalid signature", 403
event = request.json
# Process the event...
return "OK", 200
const crypto = require("crypto");
function verifyWebhook(payloadBody, signatureHeader, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(payloadBody)
.digest("hex");
const expectedSignature = `sha256=${expected}`;
return crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(signatureHeader)
);
}
// Usage in an Express route:
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
const signature = req.headers["x-golemdrive-signature"] || "";
if (!verifyWebhook(req.body, signature, WEBHOOK_SECRET)) {
return res.status(403).send("Invalid signature");
}
const event = JSON.parse(req.body);
// Process the event...
res.status(200).send("OK");
});

Important: Always use a timing-safe comparison function (like hmac.compare_digest in Python or crypto.timingSafeEqual in Node.js) to prevent timing attacks.

If your endpoint returns a non-2xx status code or doesn’t respond within 30 seconds, GolemDrive retries the delivery automatically:

AttemptDelay after failure
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry12 hours

After 5 failed retries (6 total attempts including the original), the delivery is marked as failed. You can view failed deliveries in Account Settings > Webhooks and manually retry them from there.

  • Respond with 200 quickly. Your endpoint should return a 200 status code as fast as possible. Do any heavy processing asynchronously after acknowledging receipt. If your handler takes too long, the delivery might time out and trigger unnecessary retries.
  • Use delivery_id for deduplication. In rare cases (network issues, retries), you might receive the same event twice. Store the delivery_id from each delivery and check it before processing to avoid handling duplicates.
  • Use webhook.site for testing. During development, webhook.site gives you a temporary URL that captures and displays incoming webhook payloads. It’s a quick way to inspect what GolemDrive sends without building a handler first.
  • Disable webhooks during maintenance. If your endpoint will be temporarily unavailable, disable the webhook in your dashboard settings rather than letting deliveries fail and pile up retries.
  • Keep your webhook secret safe. Treat your webhook secret like a password. Don’t commit it to version control or expose it in client-side code. Store it in environment variables or a secrets manager.