Core Concepts6 min read

How integrations work

Understand inbound routing, authentication, signing, normalization, deduplication, recovery, and safe credential operations.

Provider-native integrations convert an external webhook into the same trigger, acknowledge, and resolve model used by the Events API. They are service-scoped: the selected integration record determines which service receives the event.

text
Provider webhook
  → integration ID and key validation
  → optional provider-specific signature validation
  → payload schema and normalization
  → service-scoped deduplication
  → incident action
  → escalation and configured outbound notifications

See the integration catalog for exact routes and vendor guides.

Create an inbound integration

Application Responders and Admins can manage service integrations.

  1. Open Services, select the receiving service, and open Integrations.
  2. Select the provider type and enter a descriptive unique name.
  3. Create the integration.
  4. Copy its integration ID, provider-native URL, and generated integration key.
  5. If the provider can sign raw webhooks using the scheme supported by its OpsKnight route, rotate/create a signature secret and configure the same value at the provider.
  6. Send a synthetic trigger and recovery.

An integration record contains its ID, type, service, generated 32-character hexadecimal key, enabled state, and optional signature secret.

Authenticate provider-native routes

The standard native route shape is:

text
POST /api/integrations/PROVIDER?integrationId=INTEGRATION_ID

The request must also provide the integration key. Accepted forms are:

http
Authorization: Bearer INTEGRATION_KEY
http
Authorization: Token token=INTEGRATION_KEY
http
X-Integration-Key: INTEGRATION_KEY

X-API-Key is also accepted. For senders that cannot set headers, integrationKey, integration_key, or key query parameters are fallback options.

Prefer a header. Query values leak more easily through provider UI, browser history, proxies, access logs, and monitoring. The integration ID is not a credential and does not authorize a request by itself.

The Events API uses the integration/routing key without an integration ID; follow the Events API contract for that path.

Signature verification

When INTEGRATION_VERIFY_SIGNATURES is not false, a stored signature secret activates the signature check for routes that do not explicitly skip it. The exact header and message construction depend on the route's provider mode, such as GitHub, GitLab, Sentry, Grafana, Vercel, or generic HMAC.

Do not assume every vendor uses X-Signature or the same encoding. Follow the provider guide and validate a deliberately bad signature before production. The integration key remains required even when HMAC succeeds.

If no signature secret is stored, key validation is the baseline request authentication. If a provider cannot generate the required signature format, keep the key in a header, restrict network ingress where possible, and document the limitation.

Normalization

Each adapter maps the vendor payload to:

json
{
  "event_action": "trigger",
  "dedup_key": "provider-stable-identity",
  "payload": {
    "summary": "Human-readable alert",
    "source": "provider or monitor",
    "severity": "critical",
    "custom_details": {}
  }
}

Allowed actions are trigger, acknowledge, and resolve. Allowed normalized severities are critical, error, warning, and info. See Urgency and severity mapping.

Provider payload detail is stored as alert context and must be treated as potentially sensitive. Keep secrets and unnecessary customer data out of webhook fields.

Deduplication and recovery

Deduplication is not a global SHA-256 fingerprinting service. Each adapter deliberately constructs a stable key from provider fields such as alarm ID, monitor ID, repository/workflow, check identity, or issue ID. Event processing matches the key within the integration's service.

  • A trigger with the same service and key reuses an active Open, Acknowledged, Snoozed, or Suppressed incident.
  • An acknowledge or resolve action needs the same service and key to find the incident.
  • A key is capped at 512 characters.
  • A different integration attached to the same service can still match if it produces the same key; design adapter keys to avoid collisions.
  • A recovery with a changed key cannot close the original incident.

Test the provider's real recovery payload. A provider page showing “webhook delivered” is not evidence that OpsKnight resolved the intended incident.

Rate limiting and responses

Standard provider routes apply a per-integration PostgreSQL-backed rate limit unless INTEGRATION_RATE_LIMIT=false or a route explicitly skips it. The default integration limit is defined by the integration rate-limit configuration; rely on response headers rather than a hard-coded old-doc number.

Common results:

Status Meaning Sender action
202 Valid payload accepted and processed into an event result. Record success.
400 Missing integration ID, malformed payload, or schema error. Fix configuration; do not retry unchanged data.
401/403 Invalid key or signature. Stop retries and rotate/fix credentials.
404 Integration record not found. Recreate provider URL from the service.
429 Integration limit exceeded. Honor rate-limit headers and retry with backoff.
500 Unexpected processing failure. Retry with bounded exponential backoff and investigate logs.

Not every older route returns an identical error envelope. Test the exact provider path.

Enable, disable, rotate, and remove

Disable

The enabled flag is intended to stop event intake while preserving the record. In v1.4, legacy middleware rejects disabled integrations, but the newer standardized handler passes the flag to processors without consistently rejecting it. Verify the exact provider route before relying on the toggle, and treat key removal, network controls, or deletion as the effective stop when strict revocation is required. Track this behavior as a product defect rather than documenting the toggle as a universal security boundary.

Rotate the integration key

The UI currently generates the routing key when the integration is created; it exposes rotation for the optional signature secret, not a dedicated in-place routing-key rotation. If the routing key is exposed, create a replacement integration, update and test the sender, then delete the old integration.

Rotate or clear a signature secret

  1. Coordinate a maintenance window or provider dual-secret capability.
  2. Rotate the secret in OpsKnight.
  3. Update the provider immediately.
  4. Send valid and invalid test requests.
  5. Clear a secret only when signature verification is intentionally being removed.

Delete

Deleting an integration immediately invalidates its ID/key path and cannot be undone from the UI. Remove or update the provider destination first, preserve required audit evidence, and confirm another source covers the service.

Test without creating noise

Use an isolated service and a unique key such as docs-test/PROVIDER/TIMESTAMP:

  1. Send the smallest valid trigger.
  2. Confirm service, source, summary, urgency, and custom detail.
  3. Repeat the trigger and confirm no duplicate incident.
  4. Send acknowledge if the provider supports it.
  5. Send recovery and confirm the same incident resolves.
  6. Send a bad key, then a bad signature, and confirm rejection.
  7. Disable the integration and confirm rejection/behavior.
  8. Review Event Logs, incident timeline, notification history, and server logs.

Troubleshooting

Request says integrationId is required

Use the exact URL copied from the service integration. The routing key cannot replace the record ID in the query.

Request says invalid integration key

Confirm the key belongs to the same integration ID, remove whitespace, and use one accepted header form. Do not use a workspace API key.

Signature validation fails

Compare the provider mode, header name, secret, raw request bytes, encoding, timestamp, and any prefix such as sha256=. JSON reserialization changes the signed bytes.

Repeated alerts create duplicates

Inspect the provider guide's deduplication source and compare actual trigger payloads. Remove timestamps or random values from the identity at the provider when configurable.

Recovery does not resolve

Compare integration/service and the normalized deduplication key between trigger and recovery. Check whether the adapter recognized the recovery state.

Last updated for v1.4

Edit this page on GitHub