# AI-Powered Lead Generation

Krayin's Magic AI feature turns uploaded documents โ€” invoices, business cards, contracts โ€” into ready-to-edit leads in one click. The integration sends the parsed file to an OpenRouter (opens new window) model, which returns a structured JSON of person, contact details, and lead value that Krayin then persists.

This page documents both how to enable the feature for end users and how the developer-facing MagicAIService works under the hood.

# ๐Ÿช„ What you get

  • PDF parsing โ€” text and embedded images, powered by smalot/pdfparser (opens new window).
  • Image OCR (planned for future versions).
  • Auto-mapping โ€” AI output is mapped straight into Krayin's lead + person + email + phone schema.
  • Localised errors โ€” failure modes (bad upload, empty file, API failure) return translated user messages.

# โš™๏ธ Enable Magic AI

# 1. Get an OpenRouter API key

Sign up at OpenRouter.ai (opens new window) and create an API key from your dashboard.

# 2. Configure in the admin

  1. Open the admin panel.
  2. Go to Settings โ†’ Configuration โ†’ General โ†’ Magic AI.
  3. Toggle Magic AI on.
  4. Paste your API Key.
  5. Pick an AI model from the dropdown. Browse the full list at OpenRouter Models (opens new window) โ€” you can paste additional model IDs into the field if the one you want isn't pre-listed.
  6. Enable DOC Generation.
  7. Save.

Once saved, the Upload File control becomes available on the Leads index.

# ๐Ÿ“ Create a lead from a document

  1. Open Leads in the admin sidebar.
  2. Click Upload File.
  3. Pick a PDF or image (invoice, business card, โ€ฆ).
  4. Magic AI parses the file, extracts the structured fields, and creates a draft lead pre-filled with what it found.

The flow is especially useful for capturing offline leads โ€” trade-show business cards, scanned contracts, emailed invoices.

# ๐Ÿ”Œ Expected AI output

The AI is instructed to return a strict JSON shape. If a field can't be extracted, it falls back to a default value:

{
    "status": 1,
    "title": "Untitled Lead",
    "lead_value": 0,
    "person": {
        "name": "Unknown",
        "emails": {
            "value": null,
            "label": null
        },
        "contact_numbers": {
            "value": null,
            "label": null
        }
    }
}
Field What's extracted
title Title of the lead โ€” usually the invoice subject or project name
lead_value Monetary value of the lead (numeric)
person.name Name of the individual or contact person
person.emails.value Email address
person.emails.label Optional email label (work, personal, โ€ฆ)
person.contact_numbers.value Phone number
person.contact_numbers.label Optional phone label

# ๐Ÿ› ๏ธ Developer details โ€” MagicAIService

All of the above is orchestrated by:

Webkul\Lead\Services\MagicAIService

Responsibilities:

  • Validating + decoding Base64-encoded uploads.
  • Extracting content โ€” text and embedded images โ€” from supported file types via smalot/pdfparser.
  • Calling OpenRouter using Laravel's HTTP client with the configured API key + model.
  • Mapping the response into a valid Krayin lead payload (person, emails, phone numbers, value).

# Implementation notes

  • Concurrency protection โ€” the service holds a re-entrancy flag so the same upload can't be processed twice in parallel.
  • Temporary files โ€” uploads are written to a temp path, parsed, then deleted whether the call succeeds or fails.
  • Token-limit handling โ€” oversized documents are truncated intelligently before the prompt is built, so the request stays inside the model's context window.
  • Error path โ€” bad Base64, empty files, and AI response issues are caught and surfaced via trans() so the UI gets a localised message rather than a stack trace.

# ๐Ÿงช Verify

After saving the config:

  1. Tail the Laravel log: tail -f storage/logs/laravel.log.
  2. Upload a small test PDF from the Leads page.
  3. You should see the OpenRouter request in the log, followed by a new lead in the list.

If the upload silently does nothing, check the Magic AI section in Settings โ†’ Configuration โ†’ General โ†’ Magic AI โ€” an invalid or expired API key is the most common cause.