Skip to main content
Contafy’s SAT Search feature helps you find the correct SAT product/service code (Clave de Producto/Servicio) for your invoicing needs using natural language queries powered by artificial intelligence.

What is a SAT code?

In Mexico, every invoice (CFDI) must include a product/service code from the official SAT catalog. These codes identify what’s being invoiced and determine tax treatment. The SAT catalog (c_ClaveProdServ) contains thousands of codes with specific attributes:
export interface SATProductServiceAttributes {
  id: string;                              // Clave SAT (e.g., "80141600")
  descripcion: string;                     // Description
  incluir_iva_trasladado: "Sí" | "No" | "Opcional";
  incluir_ieps_trasladado: "Sí" | "No" | "Opcional";
  complemento_que_debe_incluir: string | null;
  fecha_inicio_vigencia: string;
  fecha_fin_vigencia: string | null;
  estimulo_franja_fronteriza: string;
  palabras_similares: string | null;
  created_at: string;
  updated_at: string;
}
SAT codes indicate whether VAT (IVA) and excise tax (IEPS) should be included. This is critical for proper tax calculation and compliance.

How SAT search works

Natural language input

Instead of browsing through thousands of codes, you describe your activity in plain Spanish:
  • “Venta de calzado deportivo”
  • “Servicios de limpieza de oficinas”
  • “Diseño gráfico publicitario”
The system uses AI to understand your query and find matching codes. The search process involves:
  1. User query analysis - GPT-4o-mini interprets your natural language description
  2. Search term extraction - AI identifies relevant keywords and synonyms
  3. Similarity matching - Vector similarity search against SAT catalog
  4. Ranking and filtering - Results ordered by relevance
  5. Confidence scoring - AI assigns confidence level (high/medium/low)
export interface AISearchResponse {
  searchTerms: string[];
  explanation: string;
  suggestedFilters?: {
    incluir_iva_trasladado?: "Sí" | "No" | "Opcional" | null;
    incluir_ieps_trasladado?: "Sí" | "No" | "Opcional" | null;
  };
  confidence: "high" | "medium" | "low";
}
The AI explanation appears in the results card, helping you understand why specific codes were suggested and how they relate to your query.

Plan limits

AI-enhanced searches are limited by subscription plan:
export interface SATPlanInfo {
  maxResults: number | null;           // Max results per search
  aiSearchesRemaining: number | null;  // Searches left this month
  aiSearchesLimit: number | null;      // Total searches per month
  aiSearchesUsed: number;              // Searches used this month
  hasAIExplanations: boolean;          // Show AI analysis
  hasHistory: boolean;                 // Save search history
  hasFavorites: boolean;               // Save favorite codes
  hasAlerts: boolean;                  // Notify on catalog updates
  hasLearning: boolean;                // Personalized suggestions
  hasAdvancedRanking: boolean;         // Better result ordering
}

Plan tiers

  • FREE - Limited AI searches per month, basic features
  • BASIC - More AI searches, AI explanations enabled
  • PREMIUM - High search limit, all features unlocked
  • ENTERPRISE - Unlimited searches (aiSearchesLimit: null)
When you reach your plan’s AI search limit, the search button is disabled and you’ll see an upgrade prompt. Your search count resets at the start of each billing cycle.

Using the search interface

The main search bar (/dashboard/sat-search) includes:
  • Text input for natural language queries
  • Real-time search counter showing remaining searches
  • AI badge indicating GPT-4o-mini powered search
  • Disabled state when limit reached

Suggestions

Before searching, common suggestion chips help you get started:
const SUGGESTIONS = [
  'Venta de calzado deportivo',
  'Servicios de limpieza de oficinas',
  'Diseño gráfico publicitario',
];
Click any suggestion to run that search instantly.

Results display

Search results show:
  • Clave SAT - The numeric code (e.g., 80141600)
  • Descripción - Official SAT description
  • IVA trasladado - Whether VAT applies (Sí/No/Opcional)
  • IEPS trasladado - Whether excise tax applies
  • Vigencia - Validity period (start and end dates)
Results are paginated (5 per page by default, respects plan limits).
Pay attention to the “incluir_iva_trasladado” field. If it says “Sí”, you must charge VAT when using this code on invoices. “Opcional” means VAT depends on your business.

AI explanation card

When AI explanations are enabled (BASIC plan and above), you’ll see:
interface SATSearchContent {
  aiExplanation?: string;
  confidence?: "high" | "medium" | "low";
}
The explanation card displays:
  • IA (GPT-4o-mini) badge - Shows AI is active
  • Confidence badge - Color-coded confidence level
    • Green (high) - AI is very confident in the results
    • Yellow (medium) - Results are likely correct
    • Gray (low) - Manual verification recommended
  • Analysis text - Explains reasoning behind results

Search state management

The search component uses React state:
const [searchQuery, setSearchQuery] = useState('');
const [results, setResults] = useState<SATProductServiceAttributes[]>([]);
const [isSearching, setIsSearching] = useState(false);
const [aiExplanation, setAiExplanation] = useState<string | undefined>();
const [confidence, setConfidence] = useState<'high' | 'medium' | 'low' | undefined>();
const [planInfo, setPlanInfo] = useState<SATPlanInfo | null>(null);
const [limitReached, setLimitReached] = useState(false);
The search flow:
  1. Check if AI searches remaining > 0
  2. If limit reached, show upgrade modal
  3. If available, call searchSATWithAI(query) server action
  4. Display results with AI explanation
  5. Update remaining count

Server action

Search is powered by a server action:
export async function searchSATWithAI(userQuery: string): Promise<SearchSATResult> {
  // Calls OpenAI GPT-4o-mini to analyze query
  // Performs similarity search against SAT catalog
  // Returns ranked results with explanation
}
The action handles:
  • Subscription limit checking
  • AI query analysis
  • Database similarity search
  • Usage tracking
  • Error handling
The SAT search uses PostgreSQL’s vector similarity features (pgvector) for efficient semantic search across thousands of product codes.

Limit reached handling

When you’ve used all AI searches:
if (planInfo?.aiSearchesRemaining === 0 || limitReached) {
  setUpgradeModalMessage(LIMIT_REACHED_MESSAGE);
  setShowUpgradeModal(true);
  return;
}
The upgrade modal appears with:
  • Current plan badge
  • Feature description
  • Recommended upgrade plan
  • Direct link to subscription management

Result pagination

Results are paginated to improve performance:
const RESULTS_PER_PAGE = 5;
const resultsPerPage = Math.min(RESULTS_PER_PAGE, planInfo?.maxResults ?? RESULTS_PER_PAGE);
const totalPages = Math.ceil(results.length / resultsPerPage);
  • Navigate with previous/next buttons
  • Click page numbers to jump
  • Pagination respects plan’s maxResults setting

Edge cases

No results

If the AI finds no matching codes:
if (results.length === 0) {
  return (
    <div className="rounded-lg border p-8 text-center">
      <p>No se encontraron resultados para tu búsqueda. Intenta con otros términos.</p>
    </div>
  );
}
Try rephrasing your query or using more specific terms.

Invalid vigencia

Some SAT codes have expiration dates (fecha_fin_vigencia). Check the vigencia field to ensure the code is currently valid.

Special requirements

The complemento_que_debe_incluir field indicates if the code requires a specific invoice complement (special XML sections). This is important for certain industries.

API endpoints

The SAT search uses these API routes:
  • GET /api/sat/stats - Returns plan limits and usage
  • POST /api/sat/search - Performs AI-enhanced search
  • GET /api/sat/similarity - Finds similar codes
  • GET /api/sat/regimenes-fiscales - Returns tax regime catalog

Technical implementation

Key files:
  • app/dashboard/sat-search/page.tsx - Main search page
  • app/dashboard/sat-search/components/SATSearchContent.tsx - Search UI logic
  • app/dashboard/sat-search/components/SATSearchBar.tsx - Search input component
  • app/dashboard/sat-search/components/SATSearchResults.tsx - Results display
  • app/dashboard/sat-search/actions.ts - Server actions for search
  • lib/types/sat.ts - TypeScript types for SAT data
  • lib/api/sat.client.ts - Client-side API calls