Likeness Search is a dual-index search system that enables buyers to find accounts (celebrity talent) by physical, visual, and voice characteristics. It powers the discovery experience on Zooly, allowing content creators to search for the perfect likeness match for their campaigns.
The Likeness Search system enables:
The system uses two complementary search indexes:
likeness_search table) - Enum-based fields for exact filtering and fast SQL querieslikeness_search_vector table) - OpenAI embeddings for semantic similarity fallback when SQL returns no resultsIndexing happens asynchronously through a queue-based system:
The system uses AI to extract searchable tags from:
For voice assets, the system creates AI-generated voice samples using the @zooly/util-elevenlabs package:
@zooly/likeness-search)The complete workflow is handled by createVoiceSample() in @zooly/util-elevenlabs.
The Likeness Search system consists of six main components:
Location: packages/db/src/schema/
likeness_assets - Stores uploaded images and voice sampleslikeness_search - SQL search index with enum fieldslikeness_search_vector - Vector embeddings for semantic searchlikeness_need_indexing_queue - Event queue for indexing pipelineaccount_social_links - Social media links and follower countsscrapes - Social media scraping resultsLocation: packages/db/src/access/
Provides type-safe database access functions for all search-related operations. See Database Access Layer for details.
Location: packages/likeness-search/src/
Package: @zooly/likeness-search
A dedicated package containing core business logic:
Voice sample creation (createVoiceSample) is in @zooly/util-elevenlabs for reuse. Embedding generation (generateEmbedding) is in @zooly/util-srv for reuse. See the respective package documentation for details.
Location: apps/zooly-app/app/api/indexing/
GET /api/indexing/process-queue - Cron endpoint for indexing daemonPOST /api/indexing/generate-tags - AI tag generation sub-processPOST /api/indexing/scrape-social - Social media scraping sub-processGET/POST /api/indexing/search - Public search endpointLocation: packages/types/src/types/
LikenessSearch.ts - Search filters and result typesLikenessAssets.ts - Asset typesLikenessQueue.ts - Queue event typesAccountSocialLink.ts - Social link typesThe system leverages shared utility packages:
@zooly/util-elevenlabs - Voice cloning and text-to-speech operations
createVoiceSample - Complete voice sample creation workflowaddVoice, deleteVoice, getVoice - Voice managementgenerateVoiceForText - Text-to-speech generation@zooly/util-srv - Server-side utilities
generateEmbedding - OpenAI embedding generation for vector search@zooly/social-scraper - Social media scraping operations
processSocialScraping - Main orchestration function for scraping all social linksThe indexing process follows these steps:
See Indexing Pipeline for detailed workflow diagrams.
Social scraping is automatically triggered during the indexing process when additional data is needed. The @zooly/social-scraper package handles scraping social media profiles to collect follower counts, profile images, and metadata.
Social scraping is triggered in two scenarios:
When triggered, the system:
triggerSocialScraping() which makes a non-blocking API call to /api/indexing/scrape-socialprocessSocialScraping() from @zooly/social-scraper which:
account_social_links tableaccount_social_links tablescrapes table for retry tracking@zooly/util-srvaccount.imageUrllikeness_assets record (type: IMAGE) for AI tag extractionSOCIAL_DATA queue event to trigger re-indexing with the new dataCOMPLETEDScraped data is integrated into the search index:
account_social_links and aggregated into a total follower count during tag aggregationlikeness_assets entries that can be processed for AI tag extractionSocial scraping includes comprehensive error handling:
The social scraping process runs asynchronously and doesn't block the main indexing pipeline, allowing parallel data collection operations.
When a buyer searches:
likeness_search table with enum-based filtersSee Search Flow for detailed search process.
The system automatically extracts searchable tags from:
Comprehensive retry handling at multiple levels:
Even with incomplete data, the system will index accounts if they have at least one image asset. This ensures maximum discoverability while still maintaining quality standards.
For voice assets, the system creates AI-generated voice samples using @zooly/util-elevenlabs that showcase the voice characteristics. This allows buyers to preview voices before licensing. The complete workflow is handled by createVoiceSample() which orchestrates voice cloning, AI-generated demo scripts, and text-to-speech generation.
On This Page
What is Likeness Search?PurposeKey ConceptsDual-Index ArchitectureEvent-Driven Indexing PipelineAI-Powered Data CollectionVoice Sample GenerationSystem Architecture1. Database Schema2. Access Layer3. Likeness Search Package4. API Routes5. Types6. Utility PackagesIndexing WorkflowSocial Scraping IntegrationWhen Social Scraping is TriggeredSocial Scraping ProcessData IntegrationError HandlingSearch FlowKey FeaturesAutomatic Tag ExtractionRetry LogicBest-Effort IndexingVoice Sample GenerationRelated Documentation