Docs Webhooks

Webhooks

Receive real-time HTTP notifications whenever events occur in your workspace — tours published, leads submitted, assets processed, and more.

How It Works

When an event occurs in your workspace, 3Syxty sends an HTTP POST request to each registered webhook URL that subscribes to that event type. The request body contains a JSON payload describing the event.

Webhooks are configured per-workspace via the Studio UI (Settings → Webhooks) or programmatically via the Webhooks API.

Event Types

Event Description
project.created A new project was created
project.updated Project settings were modified
project.deleted A project was deleted
project.published A tour was published or republished
project.unpublished A tour was unpublished
scene.created A scene was added to a project
scene.updated Scene properties were modified
scene.deleted A scene was removed
asset.uploaded A new asset was uploaded
asset.processed Asset processing (transcode, tile) completed
asset.deleted An asset was deleted
lead.submitted A lead form was submitted by a viewer
member.invited A new member was invited to the workspace
member.removed A member was removed from the workspace
quiz.completed A learner completed a quiz attempt
comment.created A new review comment was added
ai.job.completed An AI processing job finished
export.ready A self-hosted export package is ready for download

Payload Format

Every webhook delivery sends a JSON POST request with the following structure:

// POST to your webhook URL
// Content-Type: application/json

{
  "id": "evt_a1b2c3d4e5f6",
  "type": "project.published",
  "created_at": "2026-03-03T20:30:00Z",
  "workspace_id": "ws_x9y8z7",
  "data": {
    "project_id": "proj_8kF2x9mN",
    "name": "Luxury Villa Tour",
    "published_url": "https://tours.3syxty.com/t/luxury-villa",
    "scenes_count": 24
  }
}

Request Headers

Header Description
Content-Type Always application/json
X-3Syxty-Signature HMAC-SHA256 signature of the request body
X-3Syxty-Event The event type (e.g. project.published)
X-3Syxty-Delivery Unique delivery ID for idempotency tracking
User-Agent 3Syxty-Webhook/1.0

Signature Verification

Every webhook delivery is signed with your webhook secret using HMAC-SHA256. Always verify the signature to ensure the request originates from 3Syxty.

PHP verification example
// Your webhook secret (from Settings → Webhooks)
$secret = 'whsec_your_webhook_secret';

// Get the raw request body and signature header
$payload   = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_3SYXTY_SIGNATURE'] ?? '';

// Compute the expected signature
$expected = hash_hmac('sha256', $payload, $secret);

// Timing-safe comparison
if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

// Signature valid — process the event
$event = json_decode($payload, true);

Retry Policy

If your endpoint returns a non-2xx status code or fails to respond within 10 seconds, 3Syxty will retry the delivery with exponential backoff:

Attempt Delay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry (final)24 hours

After 5 failed attempts, the delivery is marked as failed. You can view failed deliveries and manually retry them via the Webhooks API or the Studio UI. Webhooks that consistently fail are automatically disabled after 100 consecutive failures.

Best Practices

Respond quickly

Return a 2xx response within 10 seconds. Process the event asynchronously if needed.

Always verify signatures

Never skip signature verification. It protects you from spoofed requests.

Handle duplicates

Use the X-3Syxty-Delivery header for idempotency. The same event may be delivered more than once during retries.

Use HTTPS endpoints

Webhook URLs must use HTTPS. HTTP endpoints are rejected.