GET
/
api
/
public
/
tags
Get all tags
curl --request GET \
  --url https://api.vambe.me/api/public/tags \
  --header 'x-api-key: <x-api-key>'
[
  {
    "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"
  }
]

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:
FieldTypeDescription
idnumberUnique numeric identifier for the tag
valuestringTag name/label (e.g., “vip-customer”)
variantstringColor variant for UI display
entity_typestringTag type: “CONTACT” or “TICKET”
created_atstring (ISO)Timestamp when the tag was created
client_idstring (UUID)Your organization ID
integration_token_idstring | nullCRM integration token ID (if synced)
integration_providerstring | nullCRM provider name (if synced)
integration_external_idstring | nullExternal CRM tag ID (if synced)

Example Request

curl --request GET \
  'https://api.vambe.ai/api/public/tags' \
  --header 'x-api-key: your_api_key_here'

Example Response

[
  {
    "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

const loadTagsForDropdown = async () => {
  const response = await fetch('https://api.vambe.ai/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

const getTagIdByName = async (tagName) => {
  const response = await fetch('https://api.vambe.ai/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

const getTagsByType = async () => {
  const response = await fetch('https://api.vambe.ai/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

const getTagsByColor = async (variant) => {
  const response = await fetch('https://api.vambe.ai/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

const buildTagFilterUI = async () => {
  const response = await fetch('https://api.vambe.ai/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

const syncTagsToExternalSystem = async () => {
  const response = await fetch('https://api.vambe.ai/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

// 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.ai/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 TypeDescriptionUse With
CONTACTTags that apply to contacts permanentlyContact-level labeling
TICKETTags that apply to tickets/conversations onlyTicket 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:
VariantTypical UseExample Tags
redUrgent, high priority, issues”urgent”, “high-priority”
amberWarning, attention needed”needs-followup”, “pending”
yellowCaution, review needed”review-required”, “on-hold”
greenSuccess, completed, positive”qualified”, “completed”
blueInformational, categories”lead”, “customer”
purpleSpecial categories”vip”, “partner”
grayNeutral, 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 CodeDescription
401Unauthorized - Invalid or missing API key
500Internal 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):
PATCH /api/public/contact/tags/{aiContactId}
Body: { "tagsIds": [1, 5, 12] }
Create Tags by Channel (Additive):
POST /api/public/channels/{channelType}/{platformIdentifier}/tags
Body: { "tags": ["vip-customer", "interested-in-premium"] }

Complete Workflow Example

// 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.ai/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.ai/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

// 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.ai/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

// 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.ai/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

const createTagLookup = async () => {
  const tags = await fetch('https://api.vambe.ai/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

const getTagsForContactForm = async () => {
  const response = await fetch('https://api.vambe.ai/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));
};

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)

Headers

x-api-key
string
required

API key needed to authorize the request

Response

Tags retrieved successfully.

id
number
Example:

1

value
string
Example:

"vip-customer"

variant
string

Color variant for UI display

Example:

"amber"

entity_type
string

CONTACT or TICKET

Example:

"CONTACT"

created_at
string
Example:

"2024-01-15T10:00:00.000Z"

client_id
string
Example:

"550e8400-e29b-41d4-a716-446655440000"