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

# Content Tags API: Categorize Wolfia Content

> Use the Wolfia tags API to retrieve and manage content tags (ACTIVE, DRAFT, REJECTED), for example, to populate dropdowns when uploading a questionnaire.

## Overview

Content tags let you categorize questionnaires and knowledge base content, so teams can organize, filter, and route work by compliance framework or topic.

Tags have three statuses:

| Status     | Meaning                                           |
| ---------- | ------------------------------------------------- |
| `ACTIVE`   | Approved and available for use                    |
| `DRAFT`    | AI-suggested, pending admin approval              |
| `REJECTED` | Rejected by an admin, hidden from default queries |

## List tags

**URL:** `GET https://api.wolfia.com/v1/tags/`

**Authentication:** API key required (see [API overview](/how-to/api-overview))

Returns all content tags for your organization, ordered alphabetically by name.

### Request

```bash theme={null}
curl -X GET 'https://api.wolfia.com/v1/tags/' \
  -H "X-API-Key: wolfia-api-YOUR_KEY_HERE"
```

### Query parameters

| Parameter | Type   | Required | Default            | Description                                        |
| --------- | ------ | -------- | ------------------ | -------------------------------------------------- |
| `status`  | string | No       | `ACTIVE` + `DRAFT` | Filter by status: `ACTIVE`, `DRAFT`, or `REJECTED` |

<Note>
  When no `status` filter is provided, the endpoint returns both `ACTIVE` and `DRAFT` tags. To retrieve only approved tags, pass `?status=ACTIVE`.
</Note>

### Response (200 OK)

```json theme={null}
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "SOC 2",
    "description": "SOC 2 compliance questionnaires",
    "is_ai_generated": false,
    "status": "ACTIVE"
  },
  {
    "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "name": "ISO 27001",
    "description": "ISO 27001 security questionnaires",
    "is_ai_generated": true,
    "status": "DRAFT"
  }
]
```

### Response fields

| Field             | Type          | Description                                                                                                            |
| ----------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `id`              | string (UUID) | Unique tag identifier; use this as `tag_ids` when [uploading questionnaires](/how-to/api-questionnaires#upload-a-file) |
| `name`            | string        | Display name of the tag                                                                                                |
| `description`     | string        | Description of the tag's purpose                                                                                       |
| `is_ai_generated` | boolean       | `true` if Wolfia's AI suggested this tag                                                                               |
| `status`          | string        | `ACTIVE`, `DRAFT`, or `REJECTED`                                                                                       |

## Integration example

### Python: Tag a questionnaire on upload

```python theme={null}
import os

import requests

API_KEY = os.environ['WOLFIA_API_KEY']
BASE_URL = 'https://api.wolfia.com/v1'


def upload_with_tags(file_path, company_name, tag_names):
    """Upload a questionnaire with matching tags applied."""
    headers = {'X-API-Key': API_KEY}

    # Fetch available tags
    tags_resp = requests.get(
        f'{BASE_URL}/tags/',
        headers=headers,
        params={'status': 'ACTIVE'},
        timeout=10,
    )
    tags_resp.raise_for_status()
    all_tags = tags_resp.json()

    # Match requested tag names (case-insensitive)
    tag_ids = [
        t['id'] for t in all_tags
        if t['name'].lower() in [n.lower() for n in tag_names]
    ]

    # Upload the questionnaire with tags
    with open(file_path, 'rb') as f:
        upload_resp = requests.post(
            f'{BASE_URL}/questionnaire/upload/file',
            headers=headers,
            files={'file': (os.path.basename(file_path), f, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')},
            data={
                'company_name': company_name,
                'tag_ids': tag_ids,
            },
            timeout=60,
        )
    upload_resp.raise_for_status()
    return upload_resp.json()


if __name__ == '__main__':
    result = upload_with_tags('questionnaire.xlsx', 'Acme Corp', ['SOC 2', 'ISO 27001'])
    print(f"Uploaded: {result['questionnaire_id']}")
```

## Error responses

| Status | Meaning                  | Solution                                                |
| ------ | ------------------------ | ------------------------------------------------------- |
| 401    | Invalid API key          | Verify your API key is correct                          |
| 403    | Insufficient permissions | Check the API key owner's role                          |
| 422    | Invalid parameters       | Ensure `status` is one of `ACTIVE`, `DRAFT`, `REJECTED` |
| 500    | Server error             | Retry with exponential backoff                          |

## Next steps

<CardGroup cols={2}>
  <Card title="Questionnaires" icon="file-circle-question" href="/how-to/api-questionnaires">
    Upload, list, and search questionnaires
  </Card>

  <Card title="API overview" icon="code" href="/how-to/api-overview">
    Authentication, rate limits, and error handling
  </Card>
</CardGroup>
