Skip to main content
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

GET /api/v1/org/webhooks
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"
}
FieldTypeRequiredDescription
urlstringYesHTTPS destination URL
eventsstring[]YesEvent types to subscribe to. Must contain at least one.
descriptionstringNoHuman-readable label for this endpoint
Supported event types
EventDescription
attestation.completedDevice successfully attested
risk_threshold_exceededDevice risk score crossed a threshold
device_blockedDevice blocked due to high risk score
Response201 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"
}
Response200 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. Response204 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