| 1 | --- |
| 2 | title: Deploy markers & annotations |
| 3 | description: Overlay deploys, incidents, and flag flips as vertical markers on Axiom charts — point or range annotations, scoped to one or more datasets, declared as alchemy resources. |
| 4 | --- |
| 5 | |
| 6 | An Axiom `Annotation` is a vertical marker overlaid on every chart |
| 7 | that queries the datasets it names — a deploy, an incident, a |
| 8 | feature-flag flip, correlated with your telemetry at a glance. In |
| 9 | alchemy it's one resource: declare it next to the services it |
| 10 | annotates, and each stage gets its own markers. |
| 11 | |
| 12 | You'll need the Axiom provider registered ([setup](/axiom/setup)) |
| 13 | and a dataset to annotate ([ingest](/axiom/data/ingest)). |
| 14 | |
| 15 | ## Drop a point marker |
| 16 | |
| 17 | ```typescript |
| 18 | import * as Axiom from "alchemy/Axiom"; |
| 19 | |
| 20 | yield* Axiom.Annotation("release-1.2.3", { |
| 21 | type: "deploy", |
| 22 | title: "Release 1.2.3", |
| 23 | datasets: ["my-app-traces"], |
| 24 | time: "2026-06-30T14:00:00Z", |
| 25 | url: "https://github.com/acme/app/releases/tag/v1.2.3", |
| 26 | }); |
| 27 | ``` |
| 28 | |
| 29 | `type` and `datasets` are the only required props. `type` is a |
| 30 | free-form string (`"deploy"`, `"incident"`, …) that groups markers |
| 31 | visually in the UI; `title`, `description`, and `url` decorate the |
| 32 | marker's tooltip. `time` is optional — omit it and Axiom stamps the |
| 33 | annotation with its creation time. Axiom assigns the annotation `id` |
| 34 | server-side and exposes it as an output. |
| 35 | |
| 36 | ## Mark a time range |
| 37 | |
| 38 | ```typescript |
| 39 | yield* Axiom.Annotation("inc-2026-04-27", { |
| 40 | type: "incident", |
| 41 | title: "Database failover", |
| 42 | datasets: ["my-app-traces"], |
| 43 | time: "2026-04-27T18:05:00Z", |
| 44 | endTime: "2026-04-27T18:32:00Z", |
| 45 | url: "https://incident.io/incidents/abc123", |
| 46 | }); |
| 47 | ``` |
| 48 | |
| 49 | Adding `endTime` turns the vertical line into a shaded band — an |
| 50 | incident window, a maintenance period, a load test. Annotations for |
| 51 | past events like this are a natural fit for resources: they stay in |
| 52 | your program, so every stage (and every rebuild of a stage) carries |
| 53 | the same incident history. |
| 54 | |
| 55 | ## Scope across datasets |
| 56 | |
| 57 | ```typescript |
| 58 | yield* Axiom.Annotation("release-1.2.3", { |
| 59 | type: "deploy", |
| 60 | title: "Release 1.2.3", |
| 61 | datasets: ["my-app-traces", "my-app-logs"], |
| 62 | time: "2026-06-30T14:00:00Z", |
| 63 | }); |
| 64 | ``` |
| 65 | |
| 66 | `datasets` takes any number of dataset names, and the marker renders |
| 67 | on charts over each of them. One annotation across your traces and |
| 68 | logs datasets keeps the deploy line in sync on both dashboards — |
| 69 | declare it once rather than duplicating per dataset. |
| 70 | |
| 71 | ## Mark each deploy |
| 72 | |
| 73 | ```typescript |
| 74 | import pkg from "./package.json" with { type: "json" }; |
| 75 | |
| 76 | yield* Axiom.Annotation(`deploy-${pkg.version}`, { |
| 77 | type: "deploy", |
| 78 | title: `Release ${pkg.version}`, |
| 79 | datasets: ["my-app-traces"], |
| 80 | time: new Date().toISOString(), |
| 81 | url: `https://github.com/acme/app/releases/tag/v${pkg.version}`, |
| 82 | }); |
| 83 | ``` |
| 84 | |
| 85 | Key the logical ID by version: bumping the version creates a fresh |
| 86 | marker at deploy time, while re-deploying the same version reconciles |
| 87 | the existing annotation in place instead of piling up duplicates — |
| 88 | the provider probes Axiom with the server-assigned `id` and only |
| 89 | creates when nothing is found. |
| 90 | |
| 91 | :::note |
| 92 | Like any resource, an annotation whose logical ID leaves the program |
| 93 | is deleted on the next deploy — so the version-keyed marker above |
| 94 | tracks the *current* release per stage, not the full release |
| 95 | history. For a permanent trail of every past deploy, create |
| 96 | annotations out-of-band at release time (Axiom's API from CI); keep |
| 97 | the resource form for markers you want reproducible per stage. |
| 98 | ::: |
| 99 | |
| 100 | ## Where next |
| 101 | |
| 102 | - [Dashboards as code](/axiom/guides/dashboards) — the charts your |
| 103 | markers land on, plus saved views. |
| 104 | - [Ingest](/axiom/data/ingest) — datasets, tokens, and wiring OTEL output |
| 105 | into Axiom. |
| 106 | - [Annotation API reference](/providers/axiom/annotation) — full |
| 107 | props and attributes. |