Skip to main content
LeadLex’s REST API is designed so any agent — the built-in Lexi, a CrewAI researcher, a LangChain tool, or a shell script — can read and write CRM data with the same ergonomics Lexi’s internal tools enjoy. This page covers the patterns an agent should use.

The read → enrich → write loop

The most common agent workflow:
1

Read context

GET /v1/contacts/{id}?include=notes,tasks,deals returns the contact plus the top 3 recent notes, open tasks, and open deals — one round-trip, no N+1.
2

Enrich

Use the embedded recent_notes / open_tasks / open_deals to build a prompt. Each contact row also has a clean first_name / last_name / full_name even if the DB is missing pieces (self-healing on read).
3

Write

POST /v1/notes with either contact_id (UUID) OR contact_name (fuzzy). The API resolves the name within the workspace. Same for company_name / company_id.
cURL — one-call context + log a note

Writing by name (fuzzy lookup)

Agents often have the human’s name but not their UUID. Every create endpoint that takes a parent link accepts both:

Disambiguation

If the fuzzy name is ambiguous, the API returns 400 ambiguous_reference with all candidate UUIDs in the message — agents should retry with the correct contact_id:
This forces agents into a deterministic flow instead of silently writing against the wrong person.

Embedded parent summaries on reads

GET /v1/notes, GET /v1/tasks, and their sub-resources return a compact linked-entity block per row so agents can render rich context without N+1 lookups:
Same for /v1/tasks (adds event too). One GET → enough data to say “Note on Hans Müller at Roche AG”.

Lexi chat vs direct REST

When should an agent use Lexi’s chat endpoint vs the REST API directly?

Agent-friendly conventions

  1. Every write accepts created_date — honored if within ±24 h / last 5 years, so you can log historical events with the real timestamp.
  2. Every note/task/meeting requires a parent linkcontact_id OR company_id OR deal_id OR event_id. Prevents silent orphans that never show up on a detail page.
  3. GET /v1/contacts/{id}?include=notes,tasks,deals is your one-call context primitive. Pass include=* for everything.
  4. Sub-resource endpoints inherit the parent from the URL — e.g. POST /v1/contacts/{id}/notes doesn’t need a body parent-link field.
  5. Workspace scope is enforced — every UUID is validated against company_id = your-workspace. Cross-tenant references return not_found.

Example: a CrewAI researcher agent

Imagine a researcher that enriches a contact from web sources and logs its findings:
No name-normalization code, no timestamp fudging, no orphan risk — the API enforces all of it.

See also