Orkestia
Blog
Product pages

CRM

Orkestia's built-in CRM keeps the people who reach your app as contacts, tracks each one as a lead through your stages, and records every touch on one timeline, through twelve crm workflows you can call directly

TL;DR

  • Contacts, leads and a timeline, built in. Each person you record (from a WhatsApp message, a web form, an import or a manual entry) becomes a contact. Each contact can have an open lead that moves through your stages. Everything that happens is one entry on the contact's timeline.
  • Twelve workflows, callable directly. Eight crm.* workflows write and four data.crm.* workflows read. Start them from the API, an SDK, an AI assistant, or as steps of a composition.
  • One CRM per app. Every call names an Identity app. Contacts of one app are never visible from another, and everything is scoped to your organization.
  • For your team, never for your app's users. Members of your organization use the CRM. Your app's end users cannot read or write it.
  • Privacy built in. Record an opt-out, and erase a person's data on request while keeping your counts and funnel history.

How it fits together

PieceWhat it isMain workflows
ContactA person, deduplicated by phone, then by email. Name, WhatsApp id, owner, tags, free attributes, where they came fromcrm.contact.upsert, crm.contact.update, data.crm.contact.list, data.crm.contact.get
LeadOne open opportunity per contact per pipeline, with a stage and an ownercrm.lead.capture, crm.lead.update-stage, crm.lead.assign, crm.lead.convert, data.crm.lead.list
TimelineNotes, messages in and out, stage changes, assignments, conversions, newest firstcrm.activity.add, data.crm.activity.list

The most common call is crm.lead.capture: someone reached you, so find or create the contact, open a lead if none is open, and log what they said. It is safe to send twice. See Contacts and leads.

Where the data lives

Orkestia stores CRM data for you, keyed to your organization and one Identity app. You do not declare tables for it, and it is separate from App Data.

The CRM is deliberately small: contacts, leads, stages and a timeline. When your process needs more, keep the extra records in App Data and link them to the CRM by contact_uuid (and lead_uuid when it applies). Typical examples:

Keep in the CRMKeep in App Data
The person, their phone and email, tags, ownerCompanies and accounts
One lead per contact and pipeline, its stage and ownerSeveral opportunities for the same person or company
Notes, messages and every stage changeTasks, reminders and their outcomes
Contact-level details in attributes (merged, so you can update one key)Scores and fields you need to filter or sort on

Lead lists filter by stage, open or closed, owner, pipeline and contact. Contact lists filter by owner, tag, source and a text search. Neither filters on attributes, so put a value you need to filter by in a tag (for example priority:high) or in App Data.

Guides

Contacts and leads

Capture, deduplication, pipelines and stages, owners, the timeline, and turning a lead into a user of your app.

Privacy and erasure

Who can see CRM data, opt-outs, and erasing a person on request.

Reference

Every crm.* and data.crm.* workflow, who may run it, errors, limits and troubleshooting.

Ask your AI assistant

prompts
Add Ana Souza, +55 11 99999-8888, as a lead in the CRM of my app "Store", source web_form.
Show me the open leads in my app "Store" that nobody owns yet.
Move Ana's lead to qualified and add a note: asked for a quote for 20 seats.
Show me the full timeline of the contact ana@example.com.

For AI agents

Do thisWith
Find the appidentity.app.query. Never ask the user for an organization_uuid: it comes from the token
Find people and leadsdata.crm.contact.list (search, tag, owner_user_uuid), data.crm.lead.list (stage, open_only, unassigned)
Read one person in fulldata.crm.contact.get, then data.crm.activity.list for the timeline
Log an inbound personcrm.lead.capture with a ref when there is an external id, so a retry does not duplicate it
Add a notecrm.activity.add (kind: note, body required)
Change stage or ownercrm.lead.update-stage, crm.lead.assign
Convert or erasecrm.lead.convert, crm.contact.erase: owner or admin only, confirm with the user first. Erasure cannot be undone

Contacts carry personal data. Show only what the user asked for, and do not copy phone numbers or emails into other systems unless asked.