> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scrubbe.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Signals API: ingest, query, and triage alert signals

> Manage observability signals: ingest from any source, query by severity or status, and triage with acknowledge, resolve, or suppress.

Signals are the raw alert events that flow into Scrubbe from monitoring tools, APM platforms, and custom integrations. The Signals API lets you ingest signals programmatically — one at a time or in bulk — query their current state, and drive lifecycle transitions: acknowledge, resolve, or suppress. Scrubbe's intelligence layer continuously correlates open signals to surface incidents and reduce alert noise, so the quality of your signal data directly affects the accuracy of incident detection.

<Note>
  All endpoints require `Authorization: Bearer <token>`. For external monitoring systems sending signals via server-to-server calls, you may also use `X-API-Key: <key>` instead of a Bearer token.
</Note>

**Base path:** `https://your-api-domain.com/api/v1/signals`

***

## List signals

Returns a paginated list of signals ordered by received time descending. Filter by severity, status, or source to narrow results for dashboards and alert queues.

`GET https://your-api-domain.com/api/v1/signals`

<ParamField query="page" type="number" default="1">Page number.</ParamField>
<ParamField query="limit" type="number" default="20">Items per page (max 100).</ParamField>

<ParamField query="status" type="string">
  Filter by status: `OPEN`, `ACKNOWLEDGED`, `RESOLVED`, or `SUPPRESSED`.
</ParamField>

<ParamField query="severity" type="string">
  Filter by severity: `LOW`, `MEDIUM`, or `HIGH`.
</ParamField>

<ParamField query="source" type="string">
  Filter by signal source (e.g. `"prometheus"`, `"datadog"`).
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://your-api-domain.com/api/v1/signals?status=OPEN&severity=HIGH \
    -H "Authorization: Bearer <token>"
  ```

  ```javascript Node.js theme={null}
  const resp = await fetch(
    'https://your-api-domain.com/api/v1/signals?status=OPEN&severity=HIGH',
    { headers: { Authorization: 'Bearer <token>' } }
  );
  const { data } = await resp.json();
  ```

  ```python Python theme={null}
  import requests

  resp = requests.get(
      'https://your-api-domain.com/api/v1/signals',
      params={'status': 'OPEN', 'severity': 'HIGH'},
      headers={'Authorization': 'Bearer <token>'},
  )
  print(resp.json())
  ```
</CodeGroup>

<ResponseField name="data" type="object[]">Array of signal objects.</ResponseField>
<ResponseField name="page" type="number">Current page number.</ResponseField>
<ResponseField name="total" type="number">Total matching signal count.</ResponseField>

***

## Get signal stats

Returns aggregate counts and trend data for signals in the workspace — total received, status breakdown, and top alerting sources.

`GET https://your-api-domain.com/api/v1/signals/stats`

```bash cURL theme={null}
curl https://your-api-domain.com/api/v1/signals/stats \
  -H "Authorization: Bearer <token>"
```

<ResponseField name="total" type="number">Total signal count.</ResponseField>
<ResponseField name="open" type="number">Signals currently in `OPEN` state.</ResponseField>
<ResponseField name="acknowledged" type="number">Signals in `ACKNOWLEDGED` state.</ResponseField>
<ResponseField name="resolved" type="number">Signals in `RESOLVED` state.</ResponseField>
<ResponseField name="suppressed" type="number">Signals in `SUPPRESSED` state.</ResponseField>

<ResponseField name="topSources" type="object[]">
  Top alerting sources by volume.

  <Expandable title="properties">
    <ResponseField name="source" type="string">Source system name.</ResponseField>
    <ResponseField name="count" type="number">Number of signals from this source.</ResponseField>
  </Expandable>
</ResponseField>

***

## Get a signal

Fetch a single signal by its ID, including its current status and all attached metadata.

`GET https://your-api-domain.com/api/v1/signals/:id`

<ParamField path="id" type="string" required>
  The signal ID.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://your-api-domain.com/api/v1/signals/SIG-20260522-00841 \
    -H "Authorization: Bearer <token>"
  ```

  ```javascript Node.js theme={null}
  const resp = await fetch(
    'https://your-api-domain.com/api/v1/signals/SIG-20260522-00841',
    { headers: { Authorization: 'Bearer <token>' } }
  );
  const signal = await resp.json();
  ```
</CodeGroup>

***

## Ingest a signal

Ingest a single alert signal into Scrubbe. Scrubbe immediately evaluates it against open signals and active correlation rules.

`POST https://your-api-domain.com/api/v1/signals`

<ParamField body="name" type="string" required>
  Short description of the alert condition (e.g. `"High error rate on /api/checkout"`).
</ParamField>

<ParamField body="source" type="string" required>
  The originating system (e.g. `"prometheus"`, `"datadog"`, `"custom"`).
</ParamField>

<ParamField body="type" type="string">
  Signal type or category, as defined by the source system.
</ParamField>

<ParamField body="severity" type="string" required>
  Severity level: `LOW`, `MEDIUM`, or `HIGH`.
</ParamField>

<ParamField body="serviceId" type="string">
  Identifier of the affected service in Scrubbe.
</ParamField>

<ParamField body="value" type="number">
  The metric value that triggered the alert (e.g. `0.23` for a 23% error rate).
</ParamField>

<ParamField body="metadata" type="object">
  Arbitrary key-value metadata from the source system (labels, tags, dimensions).
</ParamField>

<ParamField body="triggeredAt" type="string">
  ISO 8601 timestamp when the alert fired in the source system. Defaults to the time of ingestion.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://your-api-domain.com/api/v1/signals \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "High error rate on /api/checkout",
      "source": "prometheus",
      "type": "error_rate",
      "severity": "HIGH",
      "serviceId": "svc-payments",
      "value": 0.23,
      "metadata": { "env": "production", "region": "us-east-1" },
      "triggeredAt": "2026-05-22T14:30:00Z"
    }'
  ```

  ```javascript Node.js theme={null}
  const resp = await fetch('https://your-api-domain.com/api/v1/signals', {
    method: 'POST',
    headers: {
      Authorization: 'Bearer <token>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      name: 'High error rate on /api/checkout',
      source: 'prometheus',
      type: 'error_rate',
      severity: 'HIGH',
      serviceId: 'svc-payments',
      value: 0.23,
      metadata: { env: 'production', region: 'us-east-1' },
      triggeredAt: '2026-05-22T14:30:00Z',
    }),
  });
  const signal = await resp.json();
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      'https://your-api-domain.com/api/v1/signals',
      headers={'Authorization': 'Bearer <token>'},
      json={
          'name': 'High error rate on /api/checkout',
          'source': 'prometheus',
          'type': 'error_rate',
          'severity': 'HIGH',
          'serviceId': 'svc-payments',
          'value': 0.23,
          'metadata': {'env': 'production', 'region': 'us-east-1'},
          'triggeredAt': '2026-05-22T14:30:00Z',
      },
  )
  print(resp.json())
  ```
</CodeGroup>

<ResponseField name="id" type="string" required>Unique signal identifier.</ResponseField>
<ResponseField name="status" type="string" required>Initial status — always `OPEN`.</ResponseField>
<ResponseField name="createdAt" type="string" required>ISO 8601 ingestion timestamp.</ResponseField>

***

## Bulk ingest signals

Ingest multiple signals in a single request. Use this for batch ingestion from polling integrations or replay scenarios. Each signal is validated independently; partial failures are reported per item.

`POST https://your-api-domain.com/api/v1/signals/bulk`

<ParamField body="signals" type="object[]" required>
  Array of signal objects. Each follows the same schema as `POST /`.
</ParamField>

<Note>
  Bulk ingestion is limited to 100 signals per request.
</Note>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://your-api-domain.com/api/v1/signals/bulk \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{
      "signals": [
        {
          "name": "CPU spike on node-1",
          "source": "prometheus",
          "severity": "HIGH",
          "serviceId": "svc-api",
          "triggeredAt": "2026-05-22T14:29:00Z"
        },
        {
          "name": "CPU spike on node-2",
          "source": "prometheus",
          "severity": "HIGH",
          "serviceId": "svc-api",
          "triggeredAt": "2026-05-22T14:29:05Z"
        }
      ]
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      'https://your-api-domain.com/api/v1/signals/bulk',
      headers={'Authorization': 'Bearer <token>'},
      json={
          'signals': [
              {'name': 'CPU spike on node-1', 'source': 'prometheus', 'severity': 'HIGH', 'serviceId': 'svc-api', 'triggeredAt': '2026-05-22T14:29:00Z'},
              {'name': 'CPU spike on node-2', 'source': 'prometheus', 'severity': 'HIGH', 'serviceId': 'svc-api', 'triggeredAt': '2026-05-22T14:29:05Z'},
          ]
      },
  )
  print(resp.json())
  ```
</CodeGroup>

<ResponseField name="accepted" type="number">Count of signals successfully ingested.</ResponseField>
<ResponseField name="rejected" type="number">Count of signals that failed validation.</ResponseField>

<ResponseField name="results" type="object[]">
  Per-item results in input array order.

  <Expandable title="properties">
    <ResponseField name="index" type="number">Zero-based position in the input array.</ResponseField>
    <ResponseField name="id" type="string">Signal ID — present if accepted.</ResponseField>
    <ResponseField name="error" type="string">Validation error message — present if rejected.</ResponseField>
  </Expandable>
</ResponseField>

***

## Acknowledge a signal

Mark a signal as acknowledged to indicate an engineer is aware of it and investigating. Transitions the signal from `OPEN` to `ACKNOWLEDGED`.

`PATCH https://your-api-domain.com/api/v1/signals/:id/acknowledge`

<ParamField path="id" type="string" required>
  The signal ID.
</ParamField>

<ParamField body="note" type="string">
  Optional note to record alongside the acknowledgement, such as a ticket reference or on-call engineer name.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH https://your-api-domain.com/api/v1/signals/SIG-20260522-00841/acknowledge \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{ "note": "Investigating — INC-20260522-0041" }'
  ```

  ```javascript Node.js theme={null}
  const resp = await fetch(
    'https://your-api-domain.com/api/v1/signals/SIG-20260522-00841/acknowledge',
    {
      method: 'PATCH',
      headers: {
        Authorization: 'Bearer <token>',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ note: 'Investigating — INC-20260522-0041' }),
    }
  );
  ```
</CodeGroup>

***

## Resolve a signal

Mark a signal as resolved. If the signal was linked to an incident, the incident is not automatically resolved — resolve it separately via the [Incidents API](/api-reference/incidents).

`PATCH https://your-api-domain.com/api/v1/signals/:id/resolve`

<ParamField path="id" type="string" required>
  The signal ID.
</ParamField>

<ParamField body="note" type="string">
  Optional resolution note describing how the condition was cleared.
</ParamField>

```bash cURL theme={null}
curl -X PATCH https://your-api-domain.com/api/v1/signals/SIG-20260522-00841/resolve \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Restarted service — error rate returned to baseline" }'
```

***

## Suppress a signal

Suppress a signal so it no longer contributes to incident correlation or on-call notifications. Useful during known maintenance windows or for muting known-flapping alerts.

`PATCH https://your-api-domain.com/api/v1/signals/:id/suppress`

<ParamField path="id" type="string" required>
  The signal ID.
</ParamField>

<ParamField body="reason" type="string">
  Optional reason for suppression (e.g. `"maintenance window"`, `"known flap"`).
</ParamField>

<Tip>
  Use suppression rather than deletion to preserve signal history for noise analysis and alert tuning.
</Tip>

```bash cURL theme={null}
curl -X PATCH https://your-api-domain.com/api/v1/signals/SIG-20260522-00841/suppress \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Scheduled maintenance window" }'
```

***

## Signal field reference

| Field         | Type   | Description                                          |
| ------------- | ------ | ---------------------------------------------------- |
| `name`        | string | Short description of the alert condition.            |
| `source`      | string | Originating system (e.g. `prometheus`, `datadog`).   |
| `type`        | string | Signal category as defined by the source.            |
| `severity`    | string | `LOW`, `MEDIUM`, or `HIGH`.                          |
| `serviceId`   | string | Scrubbe service identifier for the affected service. |
| `value`       | number | Metric value that triggered the alert.               |
| `metadata`    | object | Arbitrary key-value pairs from the source system.    |
| `triggeredAt` | string | ISO 8601 timestamp when the alert fired.             |

| Status         | Meaning                                                       |
| -------------- | ------------------------------------------------------------- |
| `OPEN`         | Signal received, not yet actioned.                            |
| `ACKNOWLEDGED` | An engineer has seen the signal and is investigating.         |
| `RESOLVED`     | The alert condition has cleared.                              |
| `SUPPRESSED`   | Signal silenced; excluded from correlation and notifications. |
