--- name: iblai-api-crm description: Manage an ibl.ai organization's CRM via the platform API — people, organizations, pipelines and stages, lead sources, deals (with stage-move/won/lost actions), activities, and tags. Org-wide sales/relationship management. Use for lead capture, pipelines, and deal flow. metadata: kind: api --- # iblai-api-crm Manage an organization's **CRM** from the API: people and organizations, pipelines and their stages, lead sources, deals (with stage-move / won / lost actions), activities, and tags — all the sales and relationship-management records for one organization. Use for lead capture, pipelines, and deal flow. ## Auth & conventions - **Base URL:** `https://api.iblai.app/dm` — CRM is a Data Manager (DM) endpoint, so the **`/dm` prefix is required**; the `/api/crm/...` paths below are appended to it (e.g. `https://api.iblai.app/dm/api/crm/persons/`). - **Header:** `Authorization: Api-Token $IBLAI_API_KEY` on every request. (The CRM developer docs phrase this as `Authorization: Token ` — it is the same Platform API Token.) - **Scope:** Platform-scoped. Every record belongs to the organization resolved from the token, so there is **no `{org}` in the path**. - **Ids:** integers for every resource **except** Person and Organization, whose ids are **UUID** strings. - Not connected yet? Run **`/iblai-api-login`** first to populate `IBLAI_ORG`, `IBLAI_USERNAME`, and `IBLAI_API_KEY`. ## Resources | Resource | Path | Id | | ------------ | ----------------------------------------- | ------------------------------- | | Person | `/api/crm/persons/` | UUID | | Organization | `/api/crm/organizations/` | UUID | | Pipeline | `/api/crm/pipelines/` | int | | Stage | `/api/crm/pipelines/{pipeline_id}/stages/` | int (nested under a pipeline) | | Lead Source | `/api/crm/lead-sources/` | int | | Deal | `/api/crm/deals/` | int | | Activity | `/api/crm/activities/` | int | | Tag | `/api/crm/tags/` | int | Each resource supports standard REST: **GET** (list), **POST** (create), **GET** `{id}` (read), **PATCH** `{id}` (update), **DELETE** `{id}` (delete). DELETE is destructive — confirm with the user first. ### Useful filters - `owner={user_id}` — "my pipeline" / "my accounts". - `owner__isnull=true` — unowned records. - `?is_default=true` on pipelines — the seeded pipeline; its response embeds its stages inline. ## Pagination List `GET`s are page-numbered. Navigate with `?page={n}` and override the page size with `?page_size={n}` (default `50`). The list envelope is: ```json { "count": 137, "next_page": 3, "previous_page": 1, "results": [ /* … */ ] } ``` `next_page` / `previous_page` are page **numbers** (or `null` at the ends), not URLs — a detail different from stock DRF pagination. ## Reads ### Person - **GET** `/api/crm/persons/` — list people. - **GET** `/api/crm/persons/{id}/` — read a person. ### Organization - **GET** `/api/crm/organizations/` — list organizations. - **GET** `/api/crm/organizations/{id}/` — read an organization. ### Pipeline - **GET** `/api/crm/pipelines/` — list pipelines. - **GET** `/api/crm/pipelines/{id}/` — read a pipeline. ### Stage - **GET** `/api/crm/pipelines/{pipeline_id}/stages/` — list a pipeline's stages. - **GET** `/api/crm/pipelines/{pipeline_id}/stages/{id}/` — read a stage. ### Lead Source - **GET** `/api/crm/lead-sources/` — list lead sources. - **GET** `/api/crm/lead-sources/{id}/` — read a lead source. ### Deal - **GET** `/api/crm/deals/` — list deals. - **GET** `/api/crm/deals/{id}/` — read a deal. ### Activity - **GET** `/api/crm/activities/` — list activities. - **GET** `/api/crm/activities/{id}/` — read an activity. ### Tag - **GET** `/api/crm/tags/` — list tags. - **GET** `/api/crm/tags/{id}/` — read a tag. ## Writes ### Person - **POST** `/api/crm/persons/` — create a person. - **PATCH** `/api/crm/persons/{id}/` — update a person. - **DELETE** `/api/crm/persons/{id}/` — delete a person. Confirm with the user first. **Person actions:** - **POST** `/api/crm/persons/merge/` — merge duplicates into one: body `{ "primary_id": UUID, "duplicate_ids": [UUID, …] }`; reparents the duplicates' deals / activities / tags onto the primary. Destructive — confirm first. - **POST** `/api/crm/persons/{id}/invite/` — email an invitation to the person's `primary_email`. Body (all optional): `is_admin` (bool), `is_staff` (bool), `enrollment_config` (object, forwarded to auto-enroll the invitee), `redirect_to` (url). Success returns the `invitation_id`; `409` if an active invitation already exists for that email (the response carries the existing `invitation_id`, so you can track / resend it), `422` if the person is already linked to a platform user. Sends outward — confirm with the user first. - **POST** `/api/crm/persons/{id}/link-user/` — link the CRM person to an existing platform user: body `{ "user_id": int }` (required; the user must already be an active member of your org, else `403`). Sets `platform_user`. ### Organization - **POST** `/api/crm/organizations/` — create an organization. - **PATCH** `/api/crm/organizations/{id}/` — update an organization. - **DELETE** `/api/crm/organizations/{id}/` — delete an organization. Confirm with the user first. ### Pipeline - **POST** `/api/crm/pipelines/` — create a pipeline. - **PATCH** `/api/crm/pipelines/{id}/` — update a pipeline. - **DELETE** `/api/crm/pipelines/{id}/` — delete a pipeline. Confirm with the user first. ### Stage - **POST** `/api/crm/pipelines/{pipeline_id}/stages/` — create a stage. - **PATCH** `/api/crm/pipelines/{pipeline_id}/stages/{id}/` — update a stage. - **DELETE** `/api/crm/pipelines/{pipeline_id}/stages/{id}/` — delete a stage. Confirm with the user first. ### Lead Source - **POST** `/api/crm/lead-sources/` — create a lead source. - **PATCH** `/api/crm/lead-sources/{id}/` — update a lead source. - **DELETE** `/api/crm/lead-sources/{id}/` — delete a lead source. Confirm with the user first. ### Deal - **POST** `/api/crm/deals/` — create a deal. - **PATCH** `/api/crm/deals/{id}/` — update a deal. - **DELETE** `/api/crm/deals/{id}/` — delete a deal. Confirm with the user first. **Deal actions** (the canonical way to transition deals): - **PATCH** `/api/crm/deals/{id}/` — reposition `stage` within a pipeline (allowed). - **POST** `/api/crm/deals/{id}/move-stage/` — transition stage; body accepts `stage_code` (preferred) or `stage_id`. - **POST** `/api/crm/deals/{id}/won/` — close the deal as won. Body optional: `stage_code` to target a specific `is_won` stage (defaults to the pipeline's first `is_won` stage by `sort_order`). - **POST** `/api/crm/deals/{id}/lost/` — close the deal as lost. Body **requires** a non-empty `lost_reason` (≤255; `400` if missing); optional `stage_code` (defaults to the first `is_lost` stage). ### Activity - **POST** `/api/crm/activities/` — create an activity. - **PATCH** `/api/crm/activities/{id}/` — update an activity. - **DELETE** `/api/crm/activities/{id}/` — delete an activity. Confirm with the user first. - **POST** `/api/crm/activities/{id}/done/` — mark the activity done (stamps `done_at`; see `is_done`/`done_at` in the schema). ### Tag - **POST** `/api/crm/tags/` — create a tag. - **PATCH** `/api/crm/tags/{id}/` — update a tag. - **DELETE** `/api/crm/tags/{id}/` — delete a tag. Cascades — removes every assignment on every person / organization / deal. Confirm with the user first. **Attach / detach on a host** (`{host}` = `persons` | `organizations` | `deals`; both need `Ibl.CRM/Tags/write`, a **separate** RBAC bucket from host-write — see [`references/workflows.md`](references/workflows.md) § Tagging): - **POST** `/api/crm/{host}/{id}/tags/` — attach an existing tag to a host record: body `{ "tag_id": int }` (`≥ 1`). Returns `201` with `{ assignment_id, tag }`; `409` if already attached (idempotent — carries the existing `assignment_id`, so treat it as success); `404` if the tag isn't in your org. - **DELETE** `/api/crm/{host}/{id}/tags/{tag_id}/` — detach a tag (removes the assignment row, not the tag). `204` on success; `404` if it wasn't attached. Not idempotent — a repeat DELETE returns `404`; treat that as a no-op success. ## Example Create a person: ```bash curl -X POST \ "https://api.iblai.app/dm/api/crm/persons/" \ -H "Authorization: Api-Token $IBLAI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Ada Lovelace", "primary_email": "ada@example.com", "lifecycle_stage": "lead" }' ``` ## Notes - CRM is served via the DM gateway at `https://api.iblai.app/dm/api/crm/` (equivalent to the legacy `https://platform.iblai.app/api/crm/` host; skills standardize on the `api.iblai.app/dm` form). - Lifecycle stages are `lead | qualified | opportunity | customer | churned`. - A CRM Person auto-links to a Platform user when a signup matches by email. - Stages are nested under a pipeline; deal transitions go through the deal actions (`move-stage/`, `won/`, `lost/`) rather than ad-hoc edits. - Every read is scoped to your org (the token's `platform`), so a record in another org returns `404`, not `403` — existence is never leaked. Treat `404` as "not found **or** not visible to you". ## Schema Field-level request/response shape (**Mode** `req`/`opt`/`ro`) for every resource, plus the enums and the confirmed filter query params, live in a reference file to keep this skill scannable: **[`references/schema.md`](references/schema.md)**. Read it when you need exact field names, types, defaults, or which filters a list `GET` accepts. ## Reference material The endpoints and field schemas above are the authoritative, code-verified surface. These companion files (ported from the CRM developer guide) preserve the surrounding concepts, workflows, and guidance — read them for depth, not for endpoint truth: - **[`references/schema.md`](references/schema.md)** — field-level request/response shape (**Mode** `req`/`opt`/`ro`), enums, and the confirmed filter query params for every resource. - **[`references/guide.md`](references/guide.md)** — concepts & data model: system overview, write side-effects, the deal-status state machine, auth/security notes, the object graph, the resource map, and per-resource deletion/cascade behavior. - **[`references/quickstart.md`](references/quickstart.md)** — end-to-end worked walkthrough: capture a lead, find the seeded pipeline, open a deal, move it through stages, and close it won. - **[`references/workflows.md`](references/workflows.md)** — subsystem lifecycles: person onboarding (link / invite / merge / auto-link), deal lifecycle, activity timeline & auto-records, tagging, and CRM notifications (cross-refs `/iblai-api-notification`). - **[`references/operations.md`](references/operations.md)** — filtering & pagination, the RBAC role/permission matrix (cross-refs `/iblai-api-rbac`), the error reference, and best practices.