Inspiration

Sourcing new vendors for a product usually means someone building a lead list by hand — searching maps, copying phone numbers into a spreadsheet, then cold-calling each one to ask the same three questions. We wanted zero-input sourcing: give it a product and a city, and let it find real local businesses and actually call them, with a human still approving before anything real happens.

What it does

Give it a product (e.g. "leather shoes") and a location (e.g. "London, UK"). It queries OpenStreetMap for matching local businesses with phone numbers, masks and shows you the list, and — only after explicit consent — runs a two-round CALL-E outreach campaign: Round 1 qualifies interest, Round 2 captures pricing/quantity/timeline from interested vendors. Groq-based inference reads each transcript and classifies the outcome. Everything is dry-run by default; a --live flag is required to place a real call. A web dashboard shows live campaigns, a map view, analytics, and an AI chat assistant (Callie) that can run the same discover → confirm → call flow conversationally.

How we built it

  • Discovery: OpenStreetMap/Overpass API, with a keyword→tag map plus an LLM fallback for unrecognized products, geocoding via Nominatim, and multi-server failover for Overpass's rate limits.
  • Calling: CALL-E's CLI (calle call plan/run/status) wrapped in a plan → confirm → run → poll pipeline, with real-time status streamed over SSE.
  • Inference: Groq (Llama) reads call transcripts to classify interest and extract structured fields (price, timeline, contact name).
  • Safety: a consent gate that stamps a timestamp only after a human has seen the masked vendor list, a business-hours gate that resolves each vendor's timezone and fails closed if it can't, and a scheduler for retries/callbacks with cancellation support.
  • Storage/UI: SQLite, a CLI (main.py), and a Flask dashboard with a map, analytics, and an AI assistant with real tool-calling access to the pipeline.

Challenges we ran into

OpenStreetMap's phone-number coverage is excellent in some cities and nearly empty in others — a search in a small neighborhood can return zero usable vendors even though the area is real and populated, which pushed us toward wider-radius fallback searches. CALL-E's status API returns "NO ANSWER" with a space rather than an underscore, which needed explicit normalization before classification. The hardest problem was making "no call without consent" actually true in code, not just in the UI — we found and closed a path where the calling pipeline itself could self-grant consent, and moved the real check down to the actual call-dispatch function so no caller can route around it. IMPORTANT: IF AFTER VENDOR DISCOVERY ANY ERROR IS OCCURED, PLEASE SCROLL DOWN MANUALLY IN THE LEADS SECTION AND CLICK THE GREEN BUTTON FOR GIVING CONSENT TO START MAUALLY WHICH WORKS 100%.

Accomplishments that we're proud of

A real, verified CALL-E call and transcript inference running end-to-end. Dry-run is the default everywhere — a live call requires an explicit --live flag. The consent gate and business-hours gate are enforced at the lowest layer (the function that actually dials), not just the CLI prompt or the dashboard route, so no code path — including the AI assistant's own tools — can bypass them. The repository passes the target repo's own validate_repository.py and branch-naming checks.

What we learned

Safety defaults belong at the lowest layer that can actually place a call, not at the UI — anything higher can be routed around. We also learned to distrust silent success: a missing timezonefinder install had made our business-hours gate a no-op for weeks, and it only surfaced once we made "can't determine timezone" fail closed instead of open.

What's next for CALL-E Project

Additional discovery sources for regions where OpenStreetMap's phone coverage is thin, WhatsApp/SMS follow-up for vendors who don't answer a call, and CRM export for the vendors who say yes.

Built With

  • agentic
  • ai
  • calle
  • chatgpt
  • claude
  • osm
Share this project:

Updates

Submission history