> ## Documentation Index
> Fetch the complete documentation index at: https://docs.visitoai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sales CRM API

> Sales CRM API — Visito M2M API

All paths below are relative to `/m2m/v1`. Send `Authorization: Bearer <key>`. Tenant identity comes from the key.

This API uses the published sales CRM: `crm_sales_opportunities`, `crm_sales_pipelines`, and `crm_sales_audit`. Contact identity remains in `leads`; follow-ups remain in `follow_ups`.

| Method | Route                                                 | Scope             |
| ------ | ----------------------------------------------------- | ----------------- |
| GET    | `/crm/sales/configuration`                            | `crm:sales:read`  |
| GET    | `/crm/sales/opportunities`                            | `crm:sales:read`  |
| GET    | `/crm/sales/opportunities/{opportunityId}`            | `crm:sales:read`  |
| PATCH  | `/crm/sales/opportunities/{opportunityId}`            | `crm:sales:write` |
| GET    | `/crm/sales/opportunities/{opportunityId}/contact`    | `crm:sales:read`  |
| GET    | `/crm/sales/opportunities/{opportunityId}/follow-ups` | `crm:sales:read`  |

The tenant must be enrolled and have a published pipeline; unavailable tenants receive 403. Configuration exposes published fields/stages, version, enabled, and paused state, without drafts. Opportunity detail includes the latest 50 activity records.

Lists support `limit` (up to 100), opaque `cursor`, `stageId`, `status`, `group=closed`, and `includeTotal`. Closed grouping cannot be combined with stage/status. Pipeline changes invalidate scoped cursors with 409: reload configuration and restart pagination. Follow-ups support their own `limit` and `cursor` and are matched to the exact opportunity.

```json theme={null}
{"revision":3,"fieldId":"budget","value":1500}
```

```json theme={null}
{"revision":4,"stageId":"qualified"}
```

Every edit requires the current revision. On 409, reload and reconcile before retrying. Manual edits lock AI updates, including clearing a field with null. Use `{"revision":5,"fieldId":"budget","restoreAi":true}` to release a field, or omit `fieldId` to release stage control. Terminal stages close a card; closed cards cannot reopen. Edits retain the CRM's follow-up invalidation behavior.

This release does not create cards, publish pipeline configuration, or send/manage follow-ups. Subscribe to `crm.opportunity.created` and `crm.opportunity.updated` for card changes; notification data contains IDs and changed revision/stage/status, not captured values.
