Stable Contract
This telemetry reference is stable as of v1.0.0. Event names under
[:parapet, …] are frozen — renaming or removing them is a semver-major change.
Measurement and documented metadata keys may be extended in minor releases but
will not be removed or renamed without a deprecation cycle. Parapet will never
add a configurable :event_prefix option; all event names are static.
See Stability & Deprecation Policy for details.
Parapet emits telemetry as a public contract. Event names define the lifecycle seam, while metadata stays bounded and safe for downstream metrics, SLOs, and incident logic.
Versioning Contract
The telemetry event schema version is tied to the package version. Renaming or removing event names, measurements, or documented metadata fields is a semver-major change. Adding new bounded fields or measurements may be done in a minor release.
Label Safety
Phase 4 introduces a strict split between label-safe metadata and exact refs:
- Safe top-level metadata is limited to documented bounded fields such as
integration,provider,channel,queue,pipeline_stage,outcome,failure_class,delay_bucket,retry_state, andfault_plane. - Exact identifiers do not belong in top-level metadata. They are demoted into
metadata.refsusing_refkeys such asmessage_ref,delivery_ref,job_ref, orwebhook_ref. - Raw provider payloads, paths, tokens, and
*_idvalues are not part of the public contract.
Async And Delivery Families
Delivery families
[:parapet, :delivery, :outbound]
Emitted when Parapet observes an outbound provider handoff attempt.
Measurements:
count(integer) - Defaults to1.duration_ms(integer) - Duration of the observed upstream step in milliseconds when available.
Metadata:
integration- Adapter name such as:mailglass.provider- Provider or delivery backend.channel- Delivery channel such as:emailor:notification.outcome- Usually:attemptedat this seam.fault_plane- Usually:provider.refs- Optional exact identifiers such asmessage_refordelivery_ref.
[:parapet, :delivery, :provider_feedback]
Emitted when a provider response or reconciliation step yields a bounded delivery outcome.
Measurements:
count(integer)duration_ms(integer)
Metadata:
integrationproviderchanneloutcome- Bounded delivery outcomes:attempted,provider_accepted,delivered,failed, and supported extensions such asbounced,complained,suppressed.failure_class- Small bounded reason classification when relevant.fault_plane- Usually:provideror:suppression.refs
[:parapet, :delivery, :webhook_ingest]
Emitted when callback or webhook processing is the meaningful delivery seam.
Measurements:
count(integer)duration_ms(integer)delay_ms(integer) - Optional raw measurement for timing, not a label.
Metadata:
integrationproviderchanneloutcomefailure_classdelay_bucket- Bounded bucket derived from delay, not a raw value.fault_plane- Usually:webhook.refs
Async families
[:parapet, :async, :stage]
Emitted for bounded async pipeline progress.
Measurements:
count(integer)duration_ms(integer)
Metadata:
integrationprovider- Optional when the upstream system has one.queuepipeline_stageoutcome- Bounded async outcomes:started,succeeded,retryable_failed,discarded,delayed.retry_state- For examplefirst_attempt,retrying,exhausted.fault_plane- Usually:worker.refs
[:parapet, :async, :backlog]
Emitted when the primary symptom is queue or backlog pressure.
Measurements:
count(integer)delay_ms(integer) - Optional raw measurement for timing, not a label.
Metadata:
integrationproviderqueueoutcomedelay_bucketfault_plane- Usually:backlog.refs
[:parapet, :async, :callback]
Emitted when callback or reconciliation delay is distinct from internal backlog.
Measurements:
count(integer)delay_ms(integer)
Metadata:
integrationproviderqueuepipeline_stageoutcomedelay_bucketfault_plane- Usually:webhook.refs
Semantic Guarantees
provider_acceptedis not the same asdelivered.retryable_failedis not the same asdiscarded.- Callback or reconciliation delay is not the same as queue backlog.
- Public metadata is intentionally narrower than the upstream integration payloads.