Sales
Endpoint reference: ✅ Verified live against production on 10 May 2026.
“Sales” in Dr Green parlance is a lightweight CRM-style pipeline — a way to track customer interest before it becomes an order. Each sale entry has a stage (LEADS / ONGOING / CLOSED), is associated with a client, and optionally references the order it eventually became.
Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /dapp/sales | API-key + sig | Create a new sales pipeline entry |
GET | /dapp/sales | API-key + sig | List sales entries, paginated |
PATCH | /dapp/sales | API-key + sig | Update an existing sale (stage transition, etc.) |
GET | /dapp/sales/summary | API-key + sig | Counts by stage |
Stage enum
| Stage | Meaning |
|---|---|
LEADS | Initial interest captured (e.g. consultation booked, enquiry submitted) |
ONGOING | Active conversation, customer is engaged but hasn’t ordered |
CLOSED | Sale concluded — either won (linked to an order) or lost |
stage field is set by your store; the platform doesn’t auto-promote between stages. Combine with orderId to distinguish won vs. lost closures (orderId set → won; null → lost).
POST /dapp/sales — create a sale entry
Use this when a customer first expresses interest — e.g. they book a consultation, submit a contact form, or have an offline conversation your team logs in your store CRM.
Request body
PercreateSaleDto (full schema not formally declared in the spec; verified pattern):
| Field | Type | Required | Notes |
|---|---|---|---|
clientId | string (UUID) | ✅ | Must belong to the calling holder |
stage | string | ✅ | One of LEADS, ONGOING, CLOSED |
description | string | No | Free-text notes; visible in the holder’s dashboard |
orderId | string (UUID) | No | Set only when transitioning to CLOSED with a linked order |
Canonical payload (for signing)
JSON.stringify(body) — compact, no whitespace.
Response
201 Created with data.id.
🔒 Full POST response shape not yet captured live (would require a write call against production data — held off pending explicit clearance).
GET /dapp/sales — list sales
Paginated list of all sales entries for the holder.
Query parameters
| Name | Type | Default | Notes |
|---|---|---|---|
page | integer | 1 | |
limit | integer | 10 | |
stage | string | — | Filter by LEADS, ONGOING, or CLOSED |
clientId | string (UUID) | — | Filter to one client |
search | string | — | Free-text on description and client name |
Canonical payload
urlencode(query) if any params, else "{}".
Response shape (verified)
🪲descriptionisnullwhen unset (not empty string). Handle nullable in your UI.
🪲 No filterable created/updated date range at the API level — fetch wider and filter client-side if you need a time window.
Worked example (Node)
PATCH /dapp/sales — update a sale
Move a sale through the pipeline (e.g. LEADS → ONGOING → CLOSED).
Request body
PerupdateSaleDto:
| Field | Type | Required | Notes |
|---|---|---|---|
id | string (UUID) | ✅ | The sale to update |
stage | string | No | New stage |
orderId | string (UUID) | No | Link to the order this sale converted into |
description | string | No | Replaces existing description |
⚠️ Note this is PATCH /dapp/sales (no path param) — the ID goes in the body, not the URL. Unusual REST shape; mind the path.
Canonical payload
JSON.stringify(body) — compact.
Response
200 OK with data.id.
🔒 PATCH response shape not yet captured live.
GET /dapp/sales/summary — counts by stage
Canonical payload
{}
Response shape (verified)
🪲summary.totalCountandcountare duplicates — same value, two fields. Pick one.
🪲 The summary counts don’t sum tototalCountin the verified data (16 + 16 + 5 = 37, but totalCount is 19). Thesummarynumbers appear to be per-stage cumulative count over time rather than current state. Confirm with Dr Green which interpretation is intended; document accordingly. 🔒
Common patterns
Lead → won-order pipeline
Render a “won vs lost” view
Caching guidance
- Sales list: 30s TTL. Sales rep activity is real-time-ish.
- Summary: 1m TTL.
See also
- Clients — sales reference clients
- Orders — closed sales link to orders via
orderId - Commissions — commissions accrue from won sales