# Cliet Finder Spec ## Goal Define a client-key-based closed-loop client-finder flow with query expansion. ## Input - Raw input: free text query. - Normalization rule: trim and remove optional `cold-outreach:` prefix. - Expansion rule: generate expanded candidates and choose one `primaryQuery`. - Fallback: expansion failure uses normalized raw query as `primaryQuery`. ## Required Inputs - `client_key` (workflow input, passed to runner as `--client-key=<...>`) - `query` - `country` (optional, default `us`) - `AUTH_BASE` (optional runtime base URL) ## Endpoint Flow (Keyword -> Run-Flow) 1. Exchange runtime token - Method: `POST` - URL: `/auth/skill-credit/session` - Body: ```json { "clientKey": "" } ``` - Required response: `accessToken` 2. Query expansion - Source: - `QUERY_EXPANSION_JSON` (if provided and valid) - Otherwise skill built-in rule expansion - Required output: - `expandedQueries` (non-empty array) - `primaryQuery` (non-empty string) - If expansion fails, fallback to normalized raw query and mark fallback fields. 3. Execute workflow - Method: `POST` - URL: `/ecom/cold-outreach/run-flow` - Header: `Authorization: Bearer ` - Body: ```json { "query": "", "country": "us" } ``` 4. Return accepted quickly - Main runner returns `workflowId` with `workflowStatus = "accepted"`. - `runId` remains empty in immediate response. 5. Backend webhook delivery - Skill runner does not poll workflow or finalize billing. - `woo-data-scrawler` sends terminal callback using webhook config bound on the client key. ## Data Mapping Rules - Immediate response defaults: - `businessesCount = 0` - `contactsCount = 0` - `uniqueContactDomains = 0` - `billingReserveStatus = "SKIPPED"` - `billingFinalizeStatus = "SKIPPED"` ## Error Rules - If no `accessToken`, stop with auth error. - If expansion output is invalid/empty, fallback to raw query. - If no `workflowId` in run response, stop with protocol error. - If runtime reports missing hook config, stop with config error.