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

# Annotations

> Mark important events in your charts

# Annotations API

Create and manage annotations to mark important events in your Mixpanel charts.

## Base URL

```
https://mixpanel.com/api/app/projects/{projectId}/annotations
```

## Authentication

Use Service Account credentials with HTTP Basic Auth.

## List Annotations

Get all annotations in a project.

<ParamField path="projectId" type="number" required>
  Your Mixpanel project ID
</ParamField>

<ParamField query="fromDate" type="string">
  Filter annotations from this date (`YYYY-MM-DD HH:mm:ss`)
</ParamField>

<ParamField query="toDate" type="string">
  Filter annotations to this date (`YYYY-MM-DD HH:mm:ss`)
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://mixpanel.com/api/app/projects/123/annotations" \
    -u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET
  ```

  ```python Python theme={null}
  import requests
  from requests.auth import HTTPBasicAuth

  response = requests.get(
      'https://mixpanel.com/api/app/projects/123/annotations',
      auth=HTTPBasicAuth('SERVICE_ACCOUNT_USERNAME', 'SERVICE_ACCOUNT_SECRET')
  )

  annotations = response.json()
  print(f"Total annotations: {len(annotations['results'])}")
  ```
</CodeGroup>

***

## Create Annotation

Create a new annotation.

<ParamField path="projectId" type="number" required>
  Your Mixpanel project ID
</ParamField>

<ParamField body="date" type="string" required>
  Date and time in `YYYY-MM-DD HH:mm:ss` format

  Example: `2024-01-15 12:00:00`
</ParamField>

<ParamField body="description" type="string" required>
  The text to display for this annotation

  Example: `Product launch - v2.0`
</ParamField>

<ParamField body="tags" type="array">
  Array of tag IDs to associate with the annotation
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://mixpanel.com/api/app/projects/123/annotations" \
    -X POST \
    -u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET \
    -H "Content-Type: application/json" \
    -d '{
      "date": "2024-01-15 12:00:00",
      "description": "Launched new homepage design",
      "tags": [1, 2]
    }'
  ```

  ```python Python theme={null}
  import requests
  from requests.auth import HTTPBasicAuth

  response = requests.post(
      'https://mixpanel.com/api/app/projects/123/annotations',
      auth=HTTPBasicAuth('SERVICE_ACCOUNT_USERNAME', 'SERVICE_ACCOUNT_SECRET'),
      json={
          'date': '2024-01-15 12:00:00',
          'description': 'Launched new homepage design',
          'tags': [1, 2]
      }
  )

  annotation = response.json()
  print(f"Created annotation ID: {annotation['results']['id']}")
  ```
</CodeGroup>

### Response

<CodeGroup>
  ```json 201 Created theme={null}
  {
    "status": "ok",
    "results": {
      "id": 12345,
      "date": "2024-01-15 12:00:00",
      "description": "Launched new homepage design",
      "user": {
        "id": 789,
        "first_name": "John",
        "last_name": "Doe"
      },
      "tags": [
        {"id": 1, "name": "Product"},
        {"id": 2, "name": "Launch"}
      ]
    }
  }
  ```
</CodeGroup>

***

## Get Annotation

Retrieve details of a specific annotation.

<ParamField path="projectId" type="number" required>
  Your Mixpanel project ID
</ParamField>

<ParamField path="annotationId" type="number" required>
  The ID of the annotation
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://mixpanel.com/api/app/projects/123/annotations/12345" \
    -u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET
  ```
</CodeGroup>

***

## Update Annotation

Update an existing annotation.

<ParamField path="projectId" type="number" required>
  Your Mixpanel project ID
</ParamField>

<ParamField path="annotationId" type="number" required>
  The ID of the annotation to update
</ParamField>

<ParamField body="description" type="string">
  Updated description text
</ParamField>

<ParamField body="tags" type="array">
  Updated array of tag IDs
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://mixpanel.com/api/app/projects/123/annotations/12345" \
    -X PATCH \
    -u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET \
    -H "Content-Type: application/json" \
    -d '{
      "description": "Updated: Launched new homepage with A/B test",
      "tags": [1, 2, 3]
    }'
  ```

  ```python Python theme={null}
  import requests
  from requests.auth import HTTPBasicAuth

  response = requests.patch(
      'https://mixpanel.com/api/app/projects/123/annotations/12345',
      auth=HTTPBasicAuth('SERVICE_ACCOUNT_USERNAME', 'SERVICE_ACCOUNT_SECRET'),
      json={
          'description': 'Updated: Launched new homepage with A/B test',
          'tags': [1, 2, 3]
      }
  )

  print(response.json())
  ```
</CodeGroup>

***

## Delete Annotation

Permanently delete an annotation.

<ParamField path="projectId" type="number" required>
  Your Mixpanel project ID
</ParamField>

<ParamField path="annotationId" type="number" required>
  The ID of the annotation to delete
</ParamField>

### Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://mixpanel.com/api/app/projects/123/annotations/12345" \
    -X DELETE \
    -u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET
  ```

  ```python Python theme={null}
  import requests
  from requests.auth import HTTPBasicAuth

  response = requests.delete(
      'https://mixpanel.com/api/app/projects/123/annotations/12345',
      auth=HTTPBasicAuth('SERVICE_ACCOUNT_USERNAME', 'SERVICE_ACCOUNT_SECRET')
  )

  result = response.json()
  print(f"Deleted annotation ID: {result['results']['id']}")
  ```
</CodeGroup>

***

## Manage Annotation Tags

### List All Tags

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://mixpanel.com/api/app/projects/123/annotations/tags" \
    -u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET
  ```
</CodeGroup>

### Create Tag

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://mixpanel.com/api/app/projects/123/annotations/tags" \
    -X POST \
    -u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET \
    -H "Content-Type: application/json" \
    -d '{"name": "Marketing Campaign"}'
  ```

  ```python Python theme={null}
  import requests
  from requests.auth import HTTPBasicAuth

  response = requests.post(
      'https://mixpanel.com/api/app/projects/123/annotations/tags',
      auth=HTTPBasicAuth('SERVICE_ACCOUNT_USERNAME', 'SERVICE_ACCOUNT_SECRET'),
      json={'name': 'Marketing Campaign'}
  )

  tag = response.json()
  print(f"Created tag ID: {tag['id']}")
  ```
</CodeGroup>

## Best Practices

<AccordionGroup>
  <Accordion title="Use meaningful descriptions">
    Include context about what happened:

    ```python theme={null}
    {
        "description": "Product Launch: v2.0 - New checkout flow",
        "date": "2024-01-15 14:00:00"
    }
    ```
  </Accordion>

  <Accordion title="Tag annotations for filtering">
    Create tags for different categories:

    * Product launches
    * Marketing campaigns
    * Bug fixes
    * Infrastructure changes
  </Accordion>

  <Accordion title="Automate annotation creation">
    Create annotations programmatically during deployments:

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

    def create_deployment_annotation(version):
        requests.post(
            f'https://mixpanel.com/api/app/projects/{os.getenv("PROJECT_ID")}/annotations',
            auth=(os.getenv("MP_USERNAME"), os.getenv("MP_SECRET")),
            json={
                'date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'description': f'Deployed version {version}'
            }
        )
    ```
  </Accordion>
</AccordionGroup>
