Files · Mistral AI Lead Intake for ActiveCampaign SMB Lead Scoring
63 (1 binary, 520.2 kB total)attempt 1
README.md·3745 B·markdown
markdown
# Mistral AI Lead Intake for ActiveCampaign SMB Lead Scoring
> Automatically qualify and score leads from web forms, chat, or email using Mistral AI and push prioritized contacts to ActiveCampaign.
A tutorialized reference solution from [reaatech.com](https://reaatech.com), demonstrating how to build production-grade AI systems with the `@reaatech/*` package family.
## Architecture
```
form → POST /api/lead-intake → Mistral classify → ConfidenceRouter score → structured-repair-core repair → ActiveCampaign push → Langfuse telemetry
```
The pipeline receives a lead submission via the API route, classifies it using Mistral AI, scores the intent confidence via ConfidenceRouter, repairs any malformed LLM output with structured-repair-core, pushes the contact to ActiveCampaign, and traces the entire flow through Langfuse telemetry.
## Prerequisites
- Node.js >= 22
- pnpm
- ActiveCampaign account with API access
- Mistral API key
- Langfuse account
## Tech Stack
| Package | Version | Purpose |
|---------|---------|---------|
| `next` | 16.2.9 | App Router framework |
| `@mistralai/mistralai` | 2.3.0 | Mistral AI chat completions |
| `@reaatech/confidence-router` | 0.1.1 | Threshold-based decision engine |
| `@reaatech/agent-budget-engine` | 0.1.1 | Per-lead LLM spend budget enforcement |
| `@reaatech/llm-cost-telemetry` | 0.2.0 | Cost types, utilities, configuration |
| `@reaatech/structured-repair-core` | 1.0.0 | Malformed JSON repair from LLM output |
| `activecampaign` | 1.2.5 | ActiveCampaign API client |
| `langfuse` | 3.38.20 | LLM observability and tracing |
| `zod` | 4.4.3 | Runtime schema validation |
## Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `MISTRAL_API_KEY` | Yes | — | Mistral AI API key for lead classification |
| `ACTIVECAMPAIGN_API_URL` | Yes | — | ActiveCampaign API base URL |
| `ACTIVECAMPAIGN_API_KEY` | Yes | — | ActiveCampaign API key |
| `LANGFUSE_PUBLIC_KEY` | No | `""` | Langfuse public key for telemetry |
| `LANGFUSE_SECRET_KEY` | No | `""` | Langfuse secret key |
| `LANGFUSE_HOST` | No | `https://cloud.langfuse.com` | Langfuse host URL |
| `LEAD_BUDGET_LIMIT` | No | `0.05` | Per-lead LLM spend cap in USD |
| `LEAD_BUDGET_SOFT_CAP` | No | `0.8` | Ratio at which auto-downgrade triggers |
## API Reference
### POST /api/lead-intake
Accepts a lead submission and runs the full classification → scoring → push pipeline.
**Request body:**
```json
{
"name": "string (required, min 1 char)",
"email": "string (required, valid email)",
"company": "string (optional)",
"message": "string (required, min 1 char)",
"source": "string (required, enum: web_form | chat | email)"
}
```
**Success response (200):**
```json
{
"data": {
"contactId": "string",
"status": "created | updated | skipped",
"score": "number (0-100)",
"tags": ["string"],
"llmCostUsd": "number",
"processingTimeMs": "number"
}
}
```
**Error responses:**
| Status | Meaning |
|--------|---------|
| 422 | Invalid submission body (Zod validation failure) |
| 402 | Budget exceeded (hard cap reached) |
| 502 | Classification or ActiveCampaign push failure |
| 500 | Internal server error |
## Running locally
```bash
pnpm install
pnpm test # vitest run with coverage
pnpm dev # next dev
```
## Project layout
```
app/ Next.js App Router pages + API routes
src/ services, lib, adapters
tests/ vitest suite (mirrors src/)
packages/ API references for every dependency (read these first)
DEV_PLAN.md build plan for this recipe
```
## License
MIT — see [LICENSE](./LICENSE).