---
title: "ingestExternalMonitoringEvents"
method: POST
path: "/v2/integrations/{integrationId}/monitoring/external-events"
tags: ["monitoring", "integrations"]
---

# ingestExternalMonitoringEvents

`POST /v2/integrations/{integrationId}/monitoring/external-events`

Ingest monitoring spans produced by an EXTERNAL system (e.g. an integration
middleware), so the Integration Hub is the central monitoring point and the
cross-system event trace spans both the external system and epilot's own
processing.

Each span is validated, assigned a server-controlled `EXTERNAL_*` taxonomy code
derived from its `level` (the client never supplies a code — this marks
provenance and prevents spoofing an epilot code), has its `use_case_slug`
resolved against the integration's configured use cases, and is republished onto
the same monitoring event bus as epilot's own spans — so external spans are
first-class to the trace view, stats, alerting and digests.

Spans link to the epilot trace via `correlation_id` (the trace id): the middleware
must stamp the same `correlation_id` here and on the event it forwards to the
inbound endpoint. Invalid spans in a batch are reported per-item and do not fail
the whole batch.

## Path parameters

- `integrationId` string, uuid, required

## Request body

- IngestExternalMonitoringEventsRequest
  - `events` ExternalMonitoringSpan[], required — Batch of external monitoring spans (max 100 per request).
    - `correlation_id` string — Trace id — links this span to the epilot trace. Unique per business operation. Required.
    - `level` string — Span outcome level — one of success | error | warning | info. Drives the server-assigned EXTERNAL_* code, coloring, and alerting. Required.
    - `use_case_slug` string — Business use case slug (e.g. "business_partner"). Resolved server-side against the integration's configured use cases to a use_case_id/use_case_type; stored as the grouping dimension. Portable — no epilot-internal UUIDs required.
    - `occurred_at` string, date-time — External clock time the span occurred; stored as created_at.
    - `message` string — Human-readable line shown in the trace and event tables.
    - `detail` object, nullable — Free-form context (step, http_status, reason, …). The place for external-system specificity — the taxonomy code stays clean (EXTERNAL_*).

## Response `202`

Batch accepted (some spans may have been rejected — see counts).

- IngestExternalMonitoringEventsResponse
  - `accepted` integer, required — Number of spans accepted and republished onto the monitoring bus.
  - `rejected` integer, required — Number of spans rejected in validation. See `results` for reasons.
  - `results` object[] — Per-span results; present for rejections in a mixed batch.
    - `index` integer, required — Zero-based index of the span in the request `events` array.
    - `status` 'accepted' | 'rejected', required
    - `reason` string — Rejection reason (present when status is rejected).

## Other responses

- `400` — Bad request
- `401` — Unauthorized request
- `403` — Forbidden - insufficient permissions
- `404` — Resource not found
- `500` — Internal Server Error

---

[API](https://skmtc.net/epilot/apis/integration-toolkit-api.md) · [All operations](https://skmtc.net/epilot/apis/integration-toolkit-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/epilot/integration-toolkit-api/versions/c24837d75096/schema)
