Skip to main content
Version: v1 (Current)

Incoming Webhooks

Incoming webhooks are endpoints that GxP exposes for external systems to send data into the platform.

Overview

GxP provides webhook endpoints for integrating with external services like:

  • MQTT gateways for access control hardware
  • CRM systems for attendee synchronization
  • External registration platforms
  • Third-party ticketing systems

Authentication

Incoming webhooks authenticate using HMAC signatures. Each webhook source has a configured secret key that must be used to sign requests.

Signature Verification

Include the signature in the X-GxP-Signature header:

X-GxP-Signature: sha256=abc123...

Generating Signatures

$payload = json_encode($data);
$signature = hash_hmac('sha256', $payload, $webhookSecret);
const crypto = require('crypto');
const signature = crypto
.createHmac('sha256', webhookSecret)
.update(JSON.stringify(data))
.digest('hex');

Available Endpoints

MQTT Gateway Status

Receives status updates from MQTT gateway devices.

Endpoint: POST /webhook/v1/mqtt-gateway-status

Headers:

  • Content-Type: application/json
  • X-GxP-Signature: sha256={signature}

Payload:

{
"gateway_id": "GW-001",
"status": "online",
"readers": [
{
"reader_id": "READER-001",
"status": "connected",
"last_scan": "2024-01-15T10:30:00Z"
}
],
"timestamp": "2024-01-15T10:31:00Z"
}

Response:

{
"success": true,
"message": "Status updated"
}

Access Event

Receives access scan events from external readers.

Endpoint: POST /webhook/v1/access-event

Payload:

{
"reader_id": "READER-001",
"credential_value": "ABC123456",
"scan_type": "barcode",
"timestamp": "2024-01-15T14:30:00Z"
}

Response:

{
"success": true,
"access_granted": true,
"attendee": {
"id": 12345,
"first_name": "Jane",
"last_name": "Smith"
}
}

Cvent Webhook

Receives events from Cvent integration.

Endpoint: POST /webhook/v1/cvent

Headers:

  • Content-Type: application/json
  • X-Cvent-Signature: {signature}

Payload:

{
"event_type": "registration.created",
"event_id": "evt_123",
"data": {
"registration_id": "reg_456",
"attendee": {
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com"
}
},
"timestamp": "2024-01-15T09:00:00Z"
}

Supported Cvent Events:

  • registration.created
  • registration.updated
  • registration.cancelled
  • attendee.checked_in

Attendee Sync

Bulk synchronize attendees from external systems.

Endpoint: POST /webhook/v1/attendee-sync

Payload:

{
"project_slug": "my-event",
"team_slug": "my-team",
"sync_mode": "upsert",
"attendees": [
{
"external_id": "EXT-001",
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"attendee_type": "general"
}
]
}

Sync Modes:

  • upsert: Create or update based on external_id
  • create: Only create new records
  • update: Only update existing records

Response:

{
"success": true,
"results": {
"created": 5,
"updated": 10,
"skipped": 2,
"errors": []
}
}

Error Responses

Invalid Signature (401)

{
"error": "Invalid signature",
"message": "The request signature does not match"
}

Invalid Payload (400)

{
"error": "Validation failed",
"message": "The given data was invalid",
"errors": {
"attendees": ["The attendees field is required"]
}
}

Rate Limited (429)

{
"error": "Too Many Requests",
"message": "Rate limit exceeded",
"retry_after": 60
}

IP Allowlisting

For additional security, configure IP allowlists for webhook sources:

  1. Navigate to Project Settings > Integrations > Webhooks
  2. Select the webhook endpoint
  3. Add allowed IP addresses or CIDR ranges
  4. Save changes

Retry Policy

If your webhook returns an error (non-2xx response), GxP will:

  1. Not retry: Incoming webhooks do not retry
  2. Log the error: Failures are logged for debugging
  3. Return error: The calling system receives the error response

Testing Webhooks

Using cURL

# Calculate signature
PAYLOAD='{"gateway_id":"GW-001","status":"online"}'
SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "your-secret-key" | cut -d' ' -f2)

# Send webhook
curl -X POST "https://api.gramercy.cloud/webhook/v1/mqtt-gateway-status" \
-H "Content-Type: application/json" \
-H "X-GxP-Signature: sha256=$SIGNATURE" \
-d "$PAYLOAD"

Using Postman

  1. Set the request body
  2. In Pre-request Script:
    const secret = pm.environment.get('webhook_secret');
    const body = pm.request.body.raw;
    const signature = CryptoJS.HmacSHA256(body, secret).toString();
    pm.request.headers.add({key: 'X-GxP-Signature', value: 'sha256=' + signature});

Monitoring

View webhook activity in the dashboard:

  1. Navigate to Project Settings > Integrations > Webhooks
  2. Click View Logs
  3. Filter by endpoint, status, or date range

Webhook Log Entry

{
"id": "log_123",
"endpoint": "/webhook/v1/mqtt-gateway-status",
"method": "POST",
"status": 200,
"source_ip": "203.0.113.50",
"received_at": "2024-01-15T10:31:00Z",
"response_time_ms": 45
}

Best Practices

  1. Always verify signatures: Never process webhooks without signature verification
  2. Use HTTPS: All webhook URLs should use HTTPS
  3. Respond quickly: Return responses within 5 seconds
  4. Process asynchronously: Queue long-running tasks
  5. Log all requests: Keep records for debugging
  6. Monitor for failures: Set up alerts for failed webhooks