# Chart Annotations

> Mark deployments, incidents, and config changes on Uptrace charts via API so your team can correlate timeline events with metric and trace changes.

Annotations mark specific moments on your charts — deployments, incidents, config changes, feature releases — so your team can immediately correlate "what changed" with "what broke". Uptrace displays annotations as square dots on the time axis of any chart.

<video autoPlay="true" loop="true" muted="true" playsInline="true">
<source src="/features/annotations/annotations-overview.mp4" type="video/mp4" />
</video>

Clicking an annotation dot opens a popover with its name, description (supports Markdown and links to external systems), and any tags attached to it.

## Common use cases

- **Deployment markers** — post an annotation after every `kubectl apply`, `helm upgrade`, or CI/CD deploy step
- **Feature flags** — mark when a feature is enabled or rolled back in production
- **Incidents** — record incident start and end times and link to your runbook or postmortem
- **Config changes** — annotate firewall rule changes, database tuning, and scaling events
- **Canary releases** — track when a canary is promoted or rolled back

## Creating annotations

Send a `POST` request to the Uptrace API from any step in your deployment pipeline:

```shell
curl -X POST https://api.uptrace.dev/api/v1/annotations \
  -H 'uptrace-dsn: <your-dsn>' \
  -d '{"name":"Deployed v1.2.3", "attrs": {"service.version": "v1.2.3"}}'
```

Use `fingerprint` to prevent duplicate annotations when a pipeline retries:

```shell
curl -X POST https://api.uptrace.dev/api/v1/annotations \
  -H 'uptrace-dsn: <your-dsn>' \
  -d '{
    "name": "Deployed v1.2.3",
    "fingerprint": "deploy-v1.2.3",
    "color": "green",
    "attrs": {
      "deployment.environment": "production",
      "service.version": "v1.2.3"
    }
  }'
```

### Fields

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Required
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        name
      </code>
    </td>
    
    <td>
      yes
    </td>
    
    <td>
      Annotation label shown on the chart
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        description
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Markdown text shown in the popover. Supports links to runbooks, PRs, etc.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        color
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Dot color: named color (<code>
        green
      </code>
      
      , <code>
        red
      </code>
      
      , <code>
        orange
      </code>
      
      ) or hex (<code>
        #00ff00
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        attrs
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Key-value metadata (e.g. <code>
        {"deployment.environment": "production"}
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fingerprint
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Deduplication key — duplicate annotations with the same fingerprint are ignored
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        time
      </code>
    </td>
    
    <td>
      no
    </td>
    
    <td>
      Override annotation timestamp in RFC 3339 format. Defaults to request time.
    </td>
  </tr>
</tbody>
</table>

## CI/CD integration

### GitHub Actions

```yaml
- name: Annotate deployment
  run: |
    curl -sX POST https://api.uptrace.dev/api/v1/annotations \
      -H "uptrace-dsn: ${{ secrets.UPTRACE_DSN }}" \
      -d "{
        \"name\": \"Deployed ${{ github.sha }}\",
        \"fingerprint\": \"deploy-${{ github.sha }}\",
        \"color\": \"green\",
        \"description\": \"[View commit](https://github.com/${{ github.repository }}/commit/${{ github.sha }})\",
        \"attrs\": {
          \"service.version\": \"${{ github.sha }}\",
          \"deployment.environment\": \"production\"
        }
      }"
```

### GitLab CI

```yaml
annotate:
  stage: deploy
  script:
    - |
      curl -sX POST https://api.uptrace.dev/api/v1/annotations \
        -H "uptrace-dsn: ${UPTRACE_DSN}" \
        -d "{
          \"name\": \"Deployed ${CI_COMMIT_SHORT_SHA}\",
          \"fingerprint\": \"deploy-${CI_COMMIT_SHORT_SHA}\",
          \"color\": \"green\",
          \"attrs\": {\"service.version\": \"${CI_COMMIT_SHORT_SHA}\"}
        }"
```

### Shell script (post-deploy hook)

```bash
#!/bin/bash
set -euo pipefail

VERSION=$(git rev-parse --short HEAD)
curl -sX POST https://api.uptrace.dev/api/v1/annotations \
  -H "uptrace-dsn: ${UPTRACE_DSN}" \
  -d "{
    \"name\": \"Deployed ${VERSION}\",
    \"fingerprint\": \"deploy-${VERSION}\",
    \"color\": \"green\"
  }"
```

## Related

- [Metric monitors](/features/alerting/metric-monitors) — alert when a metric crosses a threshold after a deployment
- [Dashboards](/features/dashboards) — annotations are visible on all dashboard charts
- [Observability as Code](/features/observability-as-code) — manage annotations alongside your full infrastructure config
