New Relic — Ingest Setup

This guide shows how to route New Relic alerts straight to Culprit using New Relic's workflow webhook destination.


Endpoint

POST https://ingest.theculprit.ai/ingest/<tenant_id>/<service_name>/newrelic

Replace <tenant_id> and <service_name> with the values shown on your service's settings page.


Authentication

Requests must carry an ingest token in the Authorization header:

Authorization: Bearer <ingest_token>

New Relic workflow webhook destinations support custom headers, so the token rides in the standard Authorization: Bearer header rather than the URL query string.

Getting your ingest token:

  1. Open the Culprit dashboard → Services → select the service.
  2. In the Ingest token section, click Issue.
  3. Copy the token shown — it is displayed once. After you navigate away, only the token prefix is shown.

To rotate a compromised token, click Rotate. The previous token remains valid for the grace period shown, giving you time to update New Relic without an interruption.


Setup in New Relic

New Relic workflow webhook payloads are user-defined Handlebars templates. You must paste the recommended template below so Culprit receives the fields it needs. The payload is template-driven: Culprit reads priority (the raw New Relic priority field), not the stock template's remapped severity.

  1. Open Alerts → Workflows in New Relic One.
  2. Create or edit a workflow. Under Add destination, choose Webhook.
  3. Set Endpoint URL to your Culprit endpoint shown above.
  4. Under Custom Headers, add:
    • Header: Authorization
    • Value: Bearer <ingest_token>
  5. In the Payload field, replace the default content with this Handlebars template:
{ "condition_name": {{json accumulations.conditionName.[0]}},
  "priority": {{json priority}},
  "details": {{json issueTitle}},
  "incident_id": {{json issueId}},
  "incident_url": {{json issuePageUrl}},
  "state": {{json state}},
  "policy_name": {{json accumulations.policyName.[0]}} }
  1. Save the destination and enable the workflow.

How Culprit maps New Relic alerts

Field mapping

| New Relic template field | Culprit event field | Notes | |---|---|---| | details | message | Falls back to condition_name if details is absent | | condition_name | event_type | The alert condition name | | priority | severity | See severity table below | | incident_id, incident_url, state, policy_name | context | All preserved for correlation and RCA |

Severity mapping

Culprit reads the priority field from our recommended template. The stock New Relic template remaps HIGH to WARNING — Culprit handles both.

| priority value | Culprit severity | |---|---| | CRITICAL | critical | | HIGH | high | | MEDIUM or WARNING | warning | | LOW | low | | (unknown / absent) | high |

If priority is missing or unrecognized (for example a customized template that drops the field), Culprit deliberately treats the alert as high rather than discarding it — a misconfigured template surfaces as a noticeable incident instead of silently going unmonitored. Keep priority in your template to get the exact severity.

PII in any field (IP addresses, hostnames, email addresses, API keys) is detected and tokenized before any storage or notification. The original values are preserved encrypted and are visible only in the incident detail view after authentication.


Worked example

New Relic sends (after template substitution):

{
  "condition_name": "High error rate",
  "priority": "CRITICAL",
  "details": "High error rate on payments-service",
  "incident_id": "abc-123",
  "incident_url": "https://one.newrelic.com/launcher/...",
  "state": "ACTIVATED",
  "policy_name": "Production Alerts"
}

Culprit event (before tokenization):

{
  "event_type": "High error rate",
  "severity": "critical",
  "source": "newrelic",
  "message": "High error rate on payments-service",
  "context": {
    "incident_id": "abc-123",
    "incident_url": "https://one.newrelic.com/launcher/...",
    "state": "ACTIVATED",
    "policy_name": "Production Alerts"
  }
}

This event flows through the standard pipeline: encrypted vault storage → PII tokenization → storm check → embedding → correlation → root-cause analysis.


Successful response

{ "accepted": true, "ids": ["<vault_id>"] }

Error responses

| Status | Body | Meaning | |---|---|---| | 401 | { "error": "missing_auth" } | No Authorization header | | 401 | { "error": "invalid_ingest_token" } | Token is incorrect or has been rotated/revoked | | 400 | { "error": "unrecognized_payload" } | Body is not valid JSON, both details and condition_name are absent, or the payload does not match the expected shape | | 403 | { "error": "service_disabled" } | The service exists but monitoring is paused | | 404 | { "error": "service_deleted_or_not_found" } | The service does not exist | | 429 | { "error": "rate_limited" } | Storm protection active (sustained high volume) |