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

# Get all tags

> Retrieve all tags configured for your organization. Use the tag IDs for updating contact tags.

## Overview

Retrieve all tags configured for your organization. This endpoint returns tag IDs, names, types, and visual properties that you can use for contact tagging, filtering, and organization.

This is an essential endpoint for building tag selection interfaces and getting the tag IDs needed for the tag update endpoints.

## Use Cases

* **Tag Selection UI**: Populate dropdowns or multi-select components with available tags
* **Get Tag IDs**: Find tag IDs for use with update/assignment endpoints
* **Tag Management**: Display all tags in admin interfaces
* **Filtering Options**: Build dynamic filters for contacts based on available tags
* **Integration Sync**: Sync tag definitions with external systems
* **Tag Validation**: Verify tag IDs before attempting to assign them

## Authentication

This endpoint requires authentication using an API key. Include your API key in the request header:

```
x-api-key: your_api_key_here
```

## Response Structure

Returns an array of tag objects:

| Field                     | Type           | Description                           |
| ------------------------- | -------------- | ------------------------------------- |
| `id`                      | number         | Unique numeric identifier for the tag |
| `value`                   | string         | Tag name/label (e.g., "vip-customer") |
| `variant`                 | string         | Color variant for UI display          |
| `entity_type`             | string         | Tag type: "CONTACT" or "TICKET"       |
| `created_at`              | string (ISO)   | Timestamp when the tag was created    |
| `client_id`               | string (UUID)  | Your organization ID                  |
| `integration_token_id`    | string \| null | CRM integration token ID (if synced)  |
| `integration_provider`    | string \| null | CRM provider name (if synced)         |
| `integration_external_id` | string \| null | External CRM tag ID (if synced)       |

## Example Request

```bash theme={null}
curl --request GET \
  'https://api.vambe.me/api/public/tags' \
  --header 'x-api-key: your_api_key_here'
```

## Example Response

```json theme={null}
[
  {
    "id": 1,
    "value": "vip-customer",
    "variant": "amber",
    "entity_type": "CONTACT",
    "created_at": "2024-01-15T10:00:00.000Z",
    "client_id": "550e8400-e29b-41d4-a716-446655440000",
    "integration_token_id": null,
    "integration_provider": null,
    "integration_external_id": null
  },
  {
    "id": 5,
    "value": "high-priority",
    "variant": "red",
    "entity_type": "TICKET",
    "created_at": "2024-02-10T14:30:00.000Z",
    "client_id": "550e8400-e29b-41d4-a716-446655440000",
    "integration_token_id": null,
    "integration_provider": null,
    "integration_external_id": null
  },
  {
    "id": 12,
    "value": "interested-in-premium",
    "variant": "blue",
    "entity_type": "CONTACT",
    "created_at": "2024-03-05T09:15:00.000Z",
    "client_id": "550e8400-e29b-41d4-a716-446655440000",
    "integration_token_id": null,
    "integration_provider": null,
    "integration_external_id": null
  },
  {
    "id": 23,
    "value": "salesforce-lead",
    "variant": "green",
    "entity_type": "CONTACT",
    "created_at": "2024-03-20T11:00:00.000Z",
    "client_id": "550e8400-e29b-41d4-a716-446655440000",
    "integration_token_id": "660e8400-e29b-41d4-a716-446655440001",
    "integration_provider": "salesforce",
    "integration_external_id": "sf_tag_12345"
  }
]
```

## Common Use Cases

### 1. Build Tag Selection Dropdown

```javascript theme={null}
const loadTagsForDropdown = async () => {
  const response = await fetch('https://api.vambe.me/api/public/tags', {
    headers: {
      'x-api-key': 'your_api_key_here',
    },
  });

  const tags = await response.json();

  // Convert to dropdown options
  const tagOptions = tags.map((tag) => ({
    value: tag.id,
    label: tag.value,
    color: tag.variant,
    type: tag.entity_type,
  }));

  // Separate by type
  const contactTags = tagOptions.filter((t) => t.type === 'CONTACT');
  const ticketTags = tagOptions.filter((t) => t.type === 'TICKET');

  return { contactTags, ticketTags, allTags: tagOptions };
};
```

### 2. Get Tag ID by Name

```javascript theme={null}
const getTagIdByName = async (tagName) => {
  const response = await fetch('https://api.vambe.me/api/public/tags', {
    headers: {
      'x-api-key': 'your_api_key_here',
    },
  });

  const tags = await response.json();

  const tag = tags.find((t) => t.value.toLowerCase() === tagName.toLowerCase());

  if (tag) {
    console.log(`Tag "${tagName}" has ID: ${tag.id}`);
    return tag.id;
  } else {
    console.log(`Tag "${tagName}" not found`);
    return null;
  }
};

// Usage
const vipTagId = await getTagIdByName('vip-customer');
// Use this ID with PATCH /api/public/contact/tags/{aiContactId}
```

### 3. Group Tags by Type

```javascript theme={null}
const getTagsByType = async () => {
  const response = await fetch('https://api.vambe.me/api/public/tags', {
    headers: {
      'x-api-key': 'your_api_key_here',
    },
  });

  const tags = await response.json();

  const grouped = {
    contact: tags.filter((t) => t.entity_type === 'CONTACT'),
    ticket: tags.filter((t) => t.entity_type === 'TICKET'),
  };

  console.log(`Contact tags: ${grouped.contact.length}`);
  console.log(`Ticket tags: ${grouped.ticket.length}`);

  return grouped;
};
```

### 4. Get Tags by Color Variant

```javascript theme={null}
const getTagsByColor = async (variant) => {
  const response = await fetch('https://api.vambe.me/api/public/tags', {
    headers: {
      'x-api-key': 'your_api_key_here',
    },
  });

  const tags = await response.json();

  const colorTags = tags.filter((t) => t.variant === variant);

  console.log(`Found ${colorTags.length} ${variant} tags`);

  return colorTags;
};

// Usage
const redTags = await getTagsByColor('red'); // High priority tags
const greenTags = await getTagsByColor('green'); // Success/positive tags
```

### 5. Build Tag Filter Interface

```javascript theme={null}
const buildTagFilterUI = async () => {
  const response = await fetch('https://api.vambe.me/api/public/tags', {
    headers: {
      'x-api-key': 'your_api_key_here',
    },
  });

  const tags = await response.json();

  // Only show CONTACT tags for contact filtering
  const contactTags = tags.filter((t) => t.entity_type === 'CONTACT');

  return contactTags.map((tag) => ({
    id: tag.id,
    label: tag.value,
    color: tag.variant,
    onSelect: (isSelected) => {
      // Filter contacts by this tag
      if (isSelected) {
        console.log(`Filtering by tag: ${tag.value}`);
        // Call your contact filtering logic
      }
    },
  }));
};
```

### 6. Sync Tags to External System

```javascript theme={null}
const syncTagsToExternalSystem = async () => {
  const response = await fetch('https://api.vambe.me/api/public/tags', {
    headers: {
      'x-api-key': 'your_api_key_here',
    },
  });

  const tags = await response.json();

  // Sync to external system
  for (const tag of tags) {
    await fetch('https://external-system.com/api/tags/sync', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: 'Bearer external_token',
      },
      body: JSON.stringify({
        external_id: tag.id,
        name: tag.value,
        type: tag.entity_type,
        color: tag.variant,
        source: 'vambe',
      }),
    });
  }

  console.log(`Synced ${tags.length} tags to external system`);
};
```

### 7. Cache Tags for Performance

```javascript theme={null}
// Cache tags since they don't change frequently
let tagsCache = null;
let lastFetch = null;
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes

const getCachedTags = async () => {
  const now = Date.now();

  if (tagsCache && lastFetch && now - lastFetch < CACHE_DURATION) {
    console.log('Returning cached tags');
    return tagsCache;
  }

  const response = await fetch('https://api.vambe.me/api/public/tags', {
    headers: {
      'x-api-key': 'your_api_key_here',
    },
  });

  tagsCache = await response.json();
  lastFetch = now;

  console.log('Fetched and cached tags');
  return tagsCache;
};
```

## Tag Entity Types

| Entity Type | Description                                   | Use With               |
| ----------- | --------------------------------------------- | ---------------------- |
| `CONTACT`   | Tags that apply to contacts permanently       | Contact-level labeling |
| `TICKET`    | Tags that apply to tickets/conversations only | Ticket categorization  |

**Important**: TICKET tags can only be assigned to contacts that have an active ticket.

## Color Variants

Tags have color variants for visual organization in your UI:

| Variant  | Typical Use                   | Example Tags                 |
| -------- | ----------------------------- | ---------------------------- |
| `red`    | Urgent, high priority, issues | "urgent", "high-priority"    |
| `amber`  | Warning, attention needed     | "needs-followup", "pending"  |
| `yellow` | Caution, review needed        | "review-required", "on-hold" |
| `green`  | Success, completed, positive  | "qualified", "completed"     |
| `blue`   | Informational, categories     | "lead", "customer"           |
| `purple` | Special categories            | "vip", "partner"             |
| `gray`   | Neutral, archived             | "archived", "inactive"       |

## Integration Tags

Tags can be synced from external CRM systems. These have:

* `integration_token_id`: The CRM integration token
* `integration_provider`: CRM name (e.g., "salesforce", "hubspot", "pipedrive")
* `integration_external_id`: The tag ID in the external system

These allow bi-directional sync between Vambe and your CRM.

## Error Responses

| Status Code | Description                                  |
| ----------- | -------------------------------------------- |
| 401         | Unauthorized - Invalid or missing API key    |
| 500         | Internal Server Error - Something went wrong |

## Important Notes

* **Tag IDs are Numeric**: Unlike most other IDs in the API (UUIDs), tag IDs are integers
* **Organization Scoped**: Returns only tags from your organization
* **Includes Integration Tags**: Shows both manually created and CRM-synced tags
* **No Pagination**: Returns all tags (typically not a large dataset)
* **Cache-Friendly**: Tags don't change frequently, safe to cache

## Response Characteristics

* **All Tags**: Returns all tags regardless of type
* **No Filtering**: Currently no query parameters to filter tags
* **Alphabetical**: Not sorted - consider sorting client-side if needed
* **Complete List**: Includes both active and CRM-integrated tags

## Using Tag IDs

After getting tag IDs from this endpoint, use them with:

**Update Contact Tags** (Replace all):

```javascript theme={null}
PATCH /api/public/contact/tags/{aiContactId}
Body: { "tagsIds": [1, 5, 12] }
```

**Create Tags by Channel** (Additive):

```javascript theme={null}
POST /api/public/channels/{channelType}/{platformIdentifier}/tags
Body: { "tags": ["vip-customer", "interested-in-premium"] }
```

## Complete Workflow Example

```javascript theme={null}
// Complete workflow: Get tags, find IDs, assign to contact
const assignTagsToContact = async (contactId, tagNames) => {
  // 1. Get all available tags
  const tagsResponse = await fetch('https://api.vambe.me/api/public/tags', {
    headers: {
      'x-api-key': 'your_api_key_here',
    },
  });

  const allTags = await tagsResponse.json();

  // 2. Find tag IDs by name
  const tagIds = tagNames
    .map((name) => {
      const tag = allTags.find((t) => t.value === name);
      if (!tag) {
        console.warn(`Tag "${name}" not found`);
        return null;
      }
      return tag.id;
    })
    .filter((id) => id !== null);

  // 3. Assign tags to contact
  const assignResponse = await fetch(
    `https://api.vambe.me/api/public/contact/tags/${contactId}`,
    {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'your_api_key_here',
      },
      body: JSON.stringify({
        tagsIds: tagIds,
      }),
    },
  );

  const result = await assignResponse.json();
  console.log(`Assigned ${result.aiContactTagsLength} tags to contact`);

  return result;
};

// Usage
assignTagsToContact('contact-uuid', ['vip-customer', 'interested-in-premium']);
```

## Tag Display Component Example

```javascript theme={null}
// Build a tag display component with colors
const TagDisplay = ({ tags }) => {
  const colorMap = {
    red: '#EF4444',
    amber: '#F59E0B',
    yellow: '#EAB308',
    green: '#10B981',
    blue: '#3B82F6',
    purple: '#A855F7',
    gray: '#6B7280',
  };

  return tags.map((tag) => (
    <span
      key={tag.id}
      style={{
        backgroundColor: colorMap[tag.variant],
        padding: '4px 8px',
        borderRadius: '4px',
        color: 'white',
        fontSize: '12px',
      }}
    >
      {tag.value}
    </span>
  ));
};

// Load and display
const loadAndDisplayTags = async () => {
  const response = await fetch('https://api.vambe.me/api/public/tags', {
    headers: { 'x-api-key': 'your_api_key_here' },
  });

  const tags = await response.json();
  return <TagDisplay tags={tags} />;
};
```

## Best Practices

### 1. Cache Tag List

```javascript theme={null}
// Tags don't change often - cache them
const TAGS_CACHE_KEY = 'vambe_tags';
const CACHE_DURATION = 10 * 60 * 1000; // 10 minutes

const getCachedTags = async () => {
  const cached = localStorage.getItem(TAGS_CACHE_KEY);

  if (cached) {
    const { tags, timestamp } = JSON.parse(cached);
    if (Date.now() - timestamp < CACHE_DURATION) {
      return tags;
    }
  }

  const response = await fetch('https://api.vambe.me/api/public/tags', {
    headers: { 'x-api-key': 'your_api_key_here' },
  });

  const tags = await response.json();

  localStorage.setItem(
    TAGS_CACHE_KEY,
    JSON.stringify({ tags, timestamp: Date.now() }),
  );

  return tags;
};
```

### 2. Create Tag Lookup Map

```javascript theme={null}
const createTagLookup = async () => {
  const tags = await fetch('https://api.vambe.me/api/public/tags', {
    headers: { 'x-api-key': 'your_api_key_here' },
  }).then((r) => r.json());

  // By ID
  const byId = tags.reduce((acc, tag) => {
    acc[tag.id] = tag;
    return acc;
  }, {});

  // By name
  const byName = tags.reduce((acc, tag) => {
    acc[tag.value] = tag;
    return acc;
  }, {});

  return { byId, byName };
};

// Usage
const { byId, byName } = await createTagLookup();
const vipTag = byName['vip-customer'];
console.log(`VIP tag ID: ${vipTag.id}`);
```

### 3. Filter Tags by Type for UI

```javascript theme={null}
const getTagsForContactForm = async () => {
  const response = await fetch('https://api.vambe.me/api/public/tags', {
    headers: { 'x-api-key': 'your_api_key_here' },
  });

  const tags = await response.json();

  // Only show CONTACT tags in contact form (not TICKET tags)
  const contactTags = tags.filter((t) => t.entity_type === 'CONTACT');

  return contactTags.sort((a, b) => a.value.localeCompare(b.value));
};
```

## Related Endpoints

* [PATCH /api/public/contact/tags/{aiContactId}](/reference/tags/update-contact-tags) - Update contact tags using tag IDs
* [POST /api/public/channels/{channelType}/{platformIdentifier}/tags](/reference/tags/create-tags-by-channel) - Create and assign tags by name
* [GET /api/public/contact/{aiContactId}/info](/reference/contact/get-info-of-an-ai-contact) - Get contact info including assigned tags

## Performance Tips

* **Cache the Response**: Tags change infrequently - cache for 5-10 minutes
* **Client-side Operations**: Sort, filter, and search tags on the client side
* **Load Once**: Fetch tags once when your app loads, reuse throughout session
* **Update on Change**: Refresh cache when users create/edit tags in your UI

## Notes

* **No Pagination**: All tags are returned in a single response
* **Small Dataset**: Most organizations have \< 100 tags
* **Unique Names**: Tag values must be unique per organization and entity type
* **Case Sensitive**: Tag names are case-sensitive
* **ID Format**: Tag IDs are integers (not UUIDs like other resources)


## OpenAPI

````yaml get /api/public/tags
openapi: 3.0.0
info:
  title: Vambe AI API
  description: Vambe AI documentation
  version: '1.0'
  contact: {}
servers:
  - url: https://api.vambe.me
    description: Production Server
security: []
tags:
  - name: Vambe AI
    description: ''
paths:
  /api/public/tags:
    get:
      tags:
        - Tags
      summary: Get all tags
      description: >-
        Retrieve all tags configured for your organization. Use the tag IDs for
        updating contact tags.
      operationId: PublicTagsController_getTags
      parameters:
        - name: x-api-key
          in: header
          description: API key needed to authorize the request
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Tags retrieved successfully.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: number
                      example: 1
                    value:
                      type: string
                      example: vip-customer
                    variant:
                      type: string
                      example: amber
                      description: Color variant for UI display
                    entity_type:
                      type: string
                      example: CONTACT
                      description: CONTACT or TICKET
                    created_at:
                      type: string
                      example: '2024-01-15T10:00:00.000Z'
                    client_id:
                      type: string
                      example: 550e8400-e29b-41d4-a716-446655440000
        '401':
          description: Unauthorized - Invalid or missing API key.

````