Metadata-Version: 2.5
Name: crewai-layrcake
Version: 0.1.0
Summary: CrewAI tools for Layrcake: find leads, enrich and verify emails, check and research companies, and draft campaigns that a person approves before anything sends.
Project-URL: Homepage, https://layrcake.dev
Project-URL: Documentation, https://github.com/Layrcake-dev/crewai-layrcake#readme
Project-URL: Source, https://github.com/Layrcake-dev/crewai-layrcake
Project-URL: Issues, https://github.com/Layrcake-dev/crewai-layrcake/issues
Author-email: Layrcake <founders@layrcake.dev>
License-Expression: MIT
License-File: LICENSE
Keywords: agents,crewai,email-verification,layrcake,lead-generation,sales,tools
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: <3.14,>=3.11
Requires-Dist: crewai<2,>=1.0.0
Requires-Dist: layrcake[agents]<0.3.0,>=0.2.0
Requires-Dist: pydantic<3,>=2.7
Description-Content-Type: text/markdown

# crewai-layrcake

CrewAI tools for [Layrcake](https://layrcake.dev), go-to-market infrastructure for AI agents. Your crew can find leads, find and verify work emails, check and research companies, and draft email campaigns that a person approves before anything sends.

The tools wrap the official [`layrcake`](https://pypi.org/project/layrcake/) Python SDK.

## Install

```sh
pip install crewai-layrcake
```

Get an API key at [layrcake.dev/connect](https://layrcake.dev/connect) and set `LAYRCAKE_API_KEY`. New workspaces start with 300 free credits.

## Quickstart

This example uses an Anthropic model, which needs `pip install "crewai[anthropic]"`.

```python
from crewai import Agent, Crew, Task
from crewai_layrcake import layrcake_tools

sdr = Agent(
    role="SDR",
    goal="Book meetings with UK sales leaders",
    backstory="Careful with credits.",
    tools=layrcake_tools(budget_credits=50),
    llm="anthropic/claude-sonnet-5-5",
)
task = Task(
    description="Find 5 heads of sales at UK software companies, verify their work emails, "
    "draft a two-step campaign and ask for approval.",
    expected_output="The approval link.",
    agent=sdr,
)
print(Crew(agents=[sdr], tasks=[task]).kickoff())
```

The crew stops at an approval link. Nothing is sent until a person approves it in the Layrcake console.

Try it free first: `layrcake_tools(dry_run=True)` makes every call return its cost instead of data and charges nothing.

### A test run

On 20 October 2026 we ran this quickstart with `llm="openrouter/anthropic/claude-sonnet-5.5"` (crewAI reads `OPENROUTER_API_KEY`), `budget_credits=25` and this prompt: "Find 3 heads of sales at software companies in London with 20 to 200 staff, verify their work emails, and draft a short campaign about cutting time spent on lead research."

The agent called `get_me`, `find_leads`, `enrich` three times, `verify_email` three times, `create_campaign` and `launch_campaign`. It found 3 people, kept 3 verified emails (1 catch-all) and spent 21.75 of its 25 credits. It stopped at the approval link, and nothing was sent. The run took 34 seconds. The draft emails were signed with the agent's role, "SDR", so edit the sign-off before you approve.

## Tools

| Tool | What it does | Cost |
| --- | --- | --- |
| `find_leads` | Finds people who match an audience: names, titles, companies. No emails. | 0.25 credits per person found, at least 3 when anyone is found. Finding nobody is free. |
| `enrich` | Finds one person's work email from their name and company domain. | 5 credits when found. Free when not. |
| `verify_email` | Checks that an address can receive mail. | 1.25 credits per check. |
| `check_companies` | Answers one yes or no question per company from its own website, with the quote. | 3.5 credits per company answered. Unclear answers are free. |
| `research_company` | Researches one company from public sources and returns dated facts with links. | 9 credits per completed research. |
| `create_campaign` | Saves a draft email campaign for verified people. Drafts never send. | Free. |
| `launch_campaign` | Asks a person to approve the draft. Sends nothing. Returns a preview and an approval link. | Free. |
| `get_me` | Shows the workspace, the credits available and the run budget. | Free. |

1 credit is about $0.01. New workspaces start with 300 free credits. Current prices are at [docs.layrcake.dev/pricing.html](https://docs.layrcake.dev/pricing.html).

Each tool is also a class: `LayrcakeFindLeadsTool`, `LayrcakeEnrichTool`, `LayrcakeVerifyEmailTool`, `LayrcakeCheckCompaniesTool`, `LayrcakeResearchCompanyTool`, `LayrcakeCreateCampaignTool`, `LayrcakeLaunchCampaignTool` and `LayrcakeGetMeTool`. Tools built from the same `LayrcakeSession` share one run:

```python
from crewai_layrcake import LayrcakeSession, LayrcakeVerifyEmailTool

session = LayrcakeSession(budget_credits=20, dry_run=True)
print(LayrcakeVerifyEmailTool(session=session).run(email="ada@example.com"))
# {"dry_run": true, "would_cost_up_to": "1.25", "would_exceed": [], "warnings": []}
```

## How approval works

Nothing reaches a real person until a person on your side says yes.

1. `create_campaign` saves a draft. A draft never sends.
2. `launch_campaign` asks for approval. It returns `status: "needs_confirmation"`, a preview of what would send and an `approval_url`.
3. A signed-in person opens the link and approves in the Layrcake console. The Layrcake API enforces this step.
4. Only then does the campaign start sending.

The `launch_campaign` tool has no `confirmation_token` argument, and the confirmation token is removed from what the model reads, so an agent cannot approve its own send. After `launch_campaign` asks for approval, the other paid tools in the same run refuse to run, and the agent should stop and report the link.

## Run rules

The tools from one `layrcake_tools()` call share a `LayrcakeSession` from `layrcake.agent_tools`, the one implementation of these rules in the Layrcake Python SDK. It applies the rules from [layrcake.dev/agents.md](https://layrcake.dev/agents.md) in code:

- **Budget.** Every paid call sends what is left of the run budget as `budget_credits`, so the API refuses a call that could cost more. Once the budget is spent, paid tools refuse to run. The default budget is 50 credits.
- **Dry run.** With `dry_run=True`, every call returns its plan instead: the most it could cost and any limit it would trip. Nothing is looked up or charged.
- **Idempotency.** Every call sends an idempotency key derived from the run and its arguments. A repeated call returns the first answer instead of charging again. Pass the same `run_id` to resume a run safely.
- **Verified only.** `create_campaign` refuses an address that did not pass `verify_email` in this run (`valid` or `catch_all_valid`). Turn this off with `require_verified=False` if you verify elsewhere.
- **Errors as text.** API errors and refusals come back to the model as text that starts with `Refused:` and says why, such as a spent budget or missing credits, so it can fix the call or stop.

Every call goes through the official [`layrcake`](https://pypi.org/project/layrcake/) Python SDK, which handles authentication, retries and typed errors.

Arguments that do not match a tool's schema are reported to the agent by CrewAI, with the expected arguments.

## Configuration

| Argument | Default | Meaning |
| --- | --- | --- |
| `budget_credits` | `50` | The most this run may spend, in credits. |
| `dry_run` | `False` | Return each call's plan instead of running it. Free. |
| `api_key` | `LAYRCAKE_API_KEY` | Your Layrcake API key. |
| `client` | `None` | An existing `layrcake.Layrcake` client, for custom timeouts or proxies. |
| `session` | `None` | An existing `LayrcakeSession`, for `run_id` or `require_verified=False`. |

Use one `layrcake_tools()` list per crew run. Before a live `launch_campaign`, connect sending mailboxes in the [Layrcake console](https://app.layrcake.dev); without them the call returns an error that says what is missing.

## Development

```sh
uv sync
uv run ruff check . && uv run ruff format --check .
uv run mypy
uv run pytest -m "not live"
LAYRCAKE_API_KEY=... uv run pytest -m live   # dry runs only, charges nothing
```

The run rules are tested in the SDK.

## Links

- Layrcake docs: [docs.layrcake.dev](https://docs.layrcake.dev)
- For agents: [layrcake.dev/agents.md](https://layrcake.dev/agents.md)
- MCP server: `https://mcp.layrcake.dev/mcp` (also usable with CrewAI's MCP support)
- Python SDK: [github.com/Layrcake-dev/layrcake-python](https://github.com/Layrcake-dev/layrcake-python)

## License

MIT
