define.wtf
API Reference

Tags

Retrieve popular tags for autocomplete and browsing

Tags API

Tags help categorize definitions by topic, concept, or attribute. This endpoint returns the most popular tags in your workspace for use in search interfaces and autocomplete features.

GET /api/v1/tags

Returns the most frequently used tags across all definitions in your workspace, ordered by popularity.

Query Parameters

None.

Response

{
  "success": true,
  "data": [
    {
      "tag": "framework",
      "count": 24
    },
    {
      "tag": "process",
      "count": 18
    },
    {
      "tag": "technology",
      "count": 16
    },
    {
      "tag": "methodology",
      "count": 14
    },
    {
      "tag": "standard",
      "count": 12
    },
    {
      "tag": "tool",
      "count": 11
    },
    {
      "tag": "communication",
      "count": 9
    },
    {
      "tag": "management",
      "count": 8
    },
    {
      "tag": "planning",
      "count": 7
    },
    {
      "tag": "system",
      "count": 6
    }
  ]
}

Response Fields

FieldTypeDescription
tagstringTag text
countnumberNumber of definitions with this tag

Example

curl https://engineering.define.wtf/api/v1/tags \
  -H "Cookie: next-auth.session-token=YOUR_TOKEN"

Using Tags in Your Application

Tag Suggestions

Use the popular tags endpoint to provide tag suggestions when creating or editing definitions:

// Fetch popular tags for autocomplete
const response = await fetch('https://engineering.define.wtf/api/v1/tags', {
  credentials: 'include'
})
const { data } = await response.json()

// Extract just the tag strings
const tagSuggestions = data.map(item => item.tag)
// → ["framework", "process", "technology", ...]

UI Implementation

Display popular tags as:

  1. Autocomplete suggestions — Show matching tags as user types
  2. Tag cloud — Visual display with size proportional to count
  3. Frequently used list — Help users discover common tags
  4. Recent tags — Track user's own tag usage separately

Tag Best Practices

  • Keep tags lowercase — The API normalizes tags to lowercase
  • Use descriptive tags — "framework" not "f"
  • Avoid redundancy — Don't use tags that are already the acronym term
  • Be consistent — Use "process" not both "process" and "workflow"
  • Limit per definition — Recommend max 5-10 tags per definition
  • Avoid abbreviations — Users should recognize tags at a glance

Filtering by Tags

While there's no direct "filter by tag" endpoint, you can use search to find definitions with specific tags:

curl "https://engineering.define.wtf/api/v1/search?q=framework" \
  -H "Cookie: next-auth.session-token=YOUR_TOKEN"

This searches across acronym terms, titles, and definitions that include the tag or related content.


Tag Behavior

When Tags Are Used

  • Creating definitions — Attach tags when adding a definition
  • Editing definitions — Update tags on existing definitions
  • Searching — Tags are indexed for full-text search
  • Organizing — Help team members discover related content

Tag Limits

Per definition:

  • Maximum tags: 10
  • Maximum tag length: 50 characters
  • Tag format: alphanumeric, hyphens allowed, lowercase

Tag Profanity

All tags are scanned for profanity during definition creation/update. Inappropriate tags are rejected with a PROFANITY_DETECTED error.


Example: Tag-Aware Form

Here's a complete example of a definition form that uses the tags endpoint:

import { useEffect, useState } from 'react'

export function DefinitionForm() {
  const [popularTags, setPopularTags] = useState([])
  const [selectedTags, setSelectedTags] = useState([])
  const [newTag, setNewTag] = useState('')

  // Fetch popular tags on mount
  useEffect(() => {
    fetch('https://engineering.define.wtf/api/v1/tags', {
      credentials: 'include'
    })
      .then(res => res.json())
      .then(({ data }) => {
        setPopularTags(data.map(item => item.tag))
      })
  }, [])

  // Filter tags by user input
  const filteredTags = popularTags.filter(tag =>
    tag.includes(newTag.toLowerCase()) && !selectedTags.includes(tag)
  )

  const handleAddTag = (tag) => {
    setSelectedTags([...selectedTags, tag])
    setNewTag('')
  }

  const handleRemoveTag = (tag) => {
    setSelectedTags(selectedTags.filter(t => t !== tag))
  }

  const handleAddCustomTag = () => {
    if (newTag && !selectedTags.includes(newTag.toLowerCase())) {
      setSelectedTags([...selectedTags, newTag.toLowerCase()])
      setNewTag('')
    }
  }

  return (
    <form>
      <div>
        <label>Title</label>
        <input type="text" placeholder="Definition title" />
      </div>

      <div>
        <label>Tags</label>
        <div className="tag-input">
          <input
            type="text"
            placeholder="Search or create tags..."
            value={newTag}
            onChange={e => setNewTag(e.target.value)}
          />
          <button
            type="button"
            onClick={handleAddCustomTag}
            disabled={!newTag || selectedTags.includes(newTag.toLowerCase())}
          >
            Add
          </button>
        </div>

        {/* Popular tag suggestions */}
        {filteredTags.length > 0 && (
          <div className="tag-suggestions">
            {filteredTags.slice(0, 5).map(tag => (
              <button
                key={tag}
                type="button"
                onClick={() => handleAddTag(tag)}
                className="tag-suggestion"
              >
                {tag}
              </button>
            ))}
          </div>
        )}

        {/* Selected tags */}
        <div className="selected-tags">
          {selectedTags.map(tag => (
            <span key={tag} className="tag">
              {tag}
              <button
                type="button"
                onClick={() => handleRemoveTag(tag)}
              >
                ×
              </button>
            </span>
          ))}
        </div>
      </div>

      <button type="submit">Save Definition</button>
    </form>
  )
}

Error Responses

Unauthorized (401):

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Authentication required"
  }
}

Tenant not found (400):

{
  "success": false,
  "error": {
    "code": "TENANT_REQUIRED",
    "message": "Tenant context is required"
  }
}

Internal error (500):

{
  "success": false,
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "Failed to fetch tags"
  }
}

Performance

The tags endpoint returns only the top most-used tags to keep response sizes manageable. Response typically includes 10-20 tags. This prevents UI clutter and focuses on actionable suggestions.

For real-time tag filtering with user input, combine this endpoint with client-side filtering or use the autocomplete features in the definition form UI.


Caching

Consider caching the tags response client-side for improved performance:

// Cache for 1 hour
const TAGS_CACHE_TTL = 3600000 // ms

let cachedTags = null
let cacheExpiry = 0

async function getPopularTags() {
  const now = Date.now()

  if (cachedTags && now < cacheExpiry) {
    return cachedTags
  }

  const response = await fetch('https://engineering.define.wtf/api/v1/tags', {
    credentials: 'include'
  })
  const { data } = await response.json()

  cachedTags = data
  cacheExpiry = now + TAGS_CACHE_TTL

  return data
}

  • Definitions — Create and manage definitions (assign tags here)
  • Search — Full-text search that includes tag content
  • Categories — Similar to tags but hierarchical and mandatory