Documentation Index
Fetch the complete documentation index at: https://docs.grantiva.io/llms.txt
Use this file to discover all available pages before exploring further.
Webhooks are available on Pro, Business, and Enterprise plans. Endpoint limits vary by tier.
Authentication
All webhook management endpoints require a session token (cookie-based) or a gpat_/aat_ API key:
Authorization: Bearer gpat_your_personal_api_token
Callers must have Admin role or above within the organization.
List webhook endpoints
Returns all configured webhook endpoints for the organization, sorted by creation date (newest first).
Response
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://example.com/hooks/grantiva",
"events": ["attestation.completed", "risk_threshold_exceeded"],
"isActive": true,
"description": "Production event receiver",
"createdAt": "2026-03-01T12:00:00Z",
"updatedAt": "2026-03-10T08:30:00Z"
}
]
Create a webhook endpoint
POST /api/v1/org/webhooks
Request body
{
"url": "https://example.com/hooks/grantiva",
"events": ["attestation.completed", "risk_threshold_exceeded"],
"description": "Production event receiver"
}
| Field | Type | Required | Description |
|---|
url | string | Yes | HTTPS destination URL |
events | string[] | Yes | Event types to subscribe to. Must contain at least one. |
description | string | No | Human-readable label for this endpoint |
Supported event types
| Event | Description |
|---|
attestation.completed | Device successfully attested |
risk_threshold_exceeded | Device risk score crossed a threshold |
device_blocked | Device blocked due to high risk score |
Response — 201 Created
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://example.com/hooks/grantiva",
"events": ["attestation.completed"],
"isActive": true,
"description": "Production event receiver",
"secret": "whsec_abc123...",
"createdAt": "2026-03-01T12:00:00Z"
}
The secret field is returned only at creation time. Store it immediately — it cannot be retrieved again. Use it to verify the X-Grantiva-Signature header on incoming deliveries.
Update a webhook endpoint
PATCH /api/v1/org/webhooks/:id
Toggle the endpoint on/off, change subscribed events, or update the description. All fields are optional.
Request body
{
"isActive": false,
"events": ["attestation.completed", "device_blocked"],
"description": "Updated label"
}
Response — 200 OK
Returns the updated WebhookResponse object (same shape as list response, without secret).
Delete a webhook endpoint
DELETE /api/v1/org/webhooks/:id
Permanently removes the webhook endpoint. In-flight deliveries are not retried after deletion.
Response — 204 No Content
Signature verification
Every delivery includes an X-Grantiva-Signature header containing an HMAC-SHA256 signature of the raw request body, signed with your webhook’s secret.
Verify the signature before processing any payload:
import CryptoKit
func isValidSignature(payload: Data, signature: String, secret: String) -> Bool {
guard let secretData = secret.data(using: .utf8) else { return false }
let key = SymmetricKey(data: secretData)
let mac = HMAC<SHA256>.authenticationCode(for: payload, using: key)
let expected = "sha256=" + Data(mac).map { String(format: "%02x", $0) }.joined()
return expected == signature
}
For Node.js, Python, and Go examples see Webhooks Concepts.
See also