Object events
Receive a signed webhook when an object is created, deleted, or hidden—without polling a bucket.
Create a subscription
- Open Events in your PopCloud workspace.
- Choose a bucket, HTTPS endpoint, event types, and optional object-key prefix.
- Copy the signing secret. It is shown once and cannot be retrieved later.
- Send a test event and return any
2xxresponse.
A subscription can be configured before its storage source is activated. Test deliveries work immediately; the source status changes to active after PopCloud receives a valid signed storage callback.
Delivery contract
- Delivery is at least once. Store and deduplicate the stable top-level event
id. - PopCloud considers any
2xxresponse successful. - Failures retry with increasing delays. The Events page shows attempts, response status, and terminal failures.
- The endpoint must use public HTTPS. Private, loopback, link-local, and reserved destinations are rejected.
- Event types stay consistent across PopCloud regions:
object.created,object.deleted, andobject.hidden.
Verify signatures
Read the request body as bytes before parsing JSON. Compute HMAC-SHA256 with the subscription secret and compare it in constant time with X-PopCloud-Signature.
import hashlib
import hmac
def verify_popcloud_event(raw_body: bytes, signature: str, secret: str) -> bool:
expected = "v1=" + hmac.new(
secret.encode("utf-8"), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)The signature header is v1=<64 lowercase hex characters>. Re-serializing parsed JSON changes bytes and invalidates the signature.
Payload
{
"id": "0198...",
"type": "object.created",
"occurred_at": "2026-08-28T16:10:00Z",
"data": {
"bucket": "pc-example-media",
"bucket_label": "media",
"object_key": "uploads/episode-01.mp4",
"object_size": 123456789,
"object_version_id": "version-id-or-null"
}
}Useful headers
X-PopCloud-Event-Idis the same stable event identifier in the JSON body.X-PopCloud-Delivery-Ididentifies this delivery attempt series.X-PopCloud-Signatureauthenticates the exact body.
Rotation
Rotating a subscription secret invalidates the previous secret immediately. Update your endpoint before sending another test. Disable the subscription while coordinating a rotation if your deployment cannot change atomically.