AI lead qualification and scoring from your CRM
An agent reads a lead and its company from a read-only CRM, scores it against your ideal customer profile and proposes the next action.
- Files
- Read-only connection
- Callback
- Budget cap
Watch a real run
A real run on Oct 7, 2026, replayed. Model: openai/gpt-6-luna.
{
"lead_id": "lead_501"
}- Queuedbudget $0.03 reserved
- MicroVMmicroVM ready
- MicroVMworker started · shell off · web off
- Connectioncrm GET /leads/lead_501
- File
read icp.md - Result
crm GET → 200 - Connectioncrm GET /accounts/acct_91
- Result
crm GET → 200 - MicroVMmicroVM destroyed
- Succeeded3 model calls, 4,687 tokensRecorded output (English)
{ "score": 95, "tier": "A", "reasons": [ "Company has 1,200 employees, within the 100–5,000 employee ICP range.", "VP of Engineering wants to run agents over carrier APIs and requested a demo for 8 engineers.", "Lead mentioned a security review and a Q4 budget." ], "risks": [], "next_action": "Contact within a day to follow up on the demo request and discuss the security review." } - Worker destroyed$0.0036 charged, $0.0264 released
Run it yourself
Open the sample in the playground with the whole request filled in. It runs on your own account, within the budget shown, against the same read-only sample systems.
Budget for this sample: $0.03
How it works
The ideal customer profile is a file your sales team can edit. The agent reads the lead and account through a GET-only CRM connection, returns a score with reasons and risks, and never writes back to the CRM.
What the agent can and cannot do
The permissions are part of the request. Anything not listed here is not available to the run.
| Setting | Allowed |
|---|---|
| Connections | crm: GET only, at ephemer.al/api/samples/crm-api |
| Web | Off |
| Shell | Off |
| Files | icp.md (read-only) |
| Zero data retention | Off: the record is kept for 30 days |
| Budget | $0.03, a hard cap |
| Timeout | 60 seconds |
Credentials never enter the machine: a broker adds them to each call and enforces the methods above.
The code
This is the exact request the sample sends. Set EPHEMERAL_API_KEY to a member key of your organization.
curl -X POST $EPHEMERAL_URL/v1/runs \
-H "Authorization: Bearer $EPHEMERAL_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d @request.jsonFiles in the request
Passed inline, so nothing is uploaded first. The agent sees each one as a read-only file.
icp.md
# Ideal customer profile
Good fit (score up):
- Engineering or operations teams at companies with 100 to 5,000 employees.
- Wants to automate work over its own APIs (support, finance operations, monitoring).
- Mentions a security review, data retention needs, a budget or a timeline.
- Role: VP or head of engineering, operations, support or finance; or a founder with budget.
Poor fit (score down):
- Students, hobby projects, no budget or timeline.
- Individuals evaluating for someone else.
- Procurement cycles longer than 6 months for a first purchase.
Score 0 to 100. Tier A (70+): contact within a day. Tier B (40 to 69): nurture. Tier C (below 40): no sales time.
Full request body request.json
The same body, with the files inline.
{
"prompt": "Qualify the CRM lead in input.lead_id. Read the lead with GET /leads/{id} and its company with GET /accounts/{account_id}, then score it against icp.md. Reply with one JSON object and nothing else: {\"score\": number, \"tier\": \"A\"|\"B\"|\"C\", \"reasons\": string[] (max 3), \"risks\": string[] (max 2), \"next_action\": string}. Use only what the data returns and never guess; if a call fails or a field is missing, say so.",
"input": {
"lead_id": "lead_501"
},
"files": [
{
"path": "icp.md",
"content": "# Ideal customer profile\n\nGood fit (score up):\n- Engineering or operations teams at companies with 100 to 5,000 employees.\n- Wants to automate work over its own APIs (support, finance operations, monitoring).\n- Mentions a security review, data retention needs, a budget or a timeline.\n- Role: VP or head of engineering, operations, support or finance; or a founder with budget.\n\nPoor fit (score down):\n- Students, hobby projects, no budget or timeline.\n- Individuals evaluating for someone else.\n- Procurement cycles longer than 6 months for a first purchase.\n\nScore 0 to 100. Tier A (70+): contact within a day. Tier B (40 to 69): nurture. Tier C (below 40): no sales time.\n"
}
],
"connections": {
"crm": {
"type": "http",
"url": "https://ephemer.al/api/samples/crm-api",
"auth": {
"type": "bearer",
"token": "sample_read_key"
},
"allowed_methods": [
"GET"
],
"instructions": "A CRM. GET /leads lists leads. GET /leads/{id} returns a lead with notes and activity. GET /accounts/{id} returns the company (industry, employees, country, revenue, tech, customer, open_deals)."
}
},
"shell": false,
"timeout_seconds": 60,
"max_cost_micros": 30000
}