Skip to main content

Clients (Customers)

Endpoint reference: ✅ Verified live against production on 10 May 2026. “Clients” in Dr Green parlance are your store’s end customers. They’re scoped to the holder’s primary NFT — so all clients you create via your store belong to the holder whose apiKey you’re using. KYC, addresses, business details, and medical records all hang off the client record.

Endpoints

🪲 Naming inconsistency in the API: sub-routes are split between /dapp/clients/{clientId}/... and /dapp/client/{clientId}/... (singular vs plural). This is a backend wart — not a typo in this doc. Use whichever path each endpoint expects.

Status enums

Clients have three relevant status fields: A client must be adminApproval: VERIFIED AND isKYCVerified: true AND isActive: true before they can place orders. New clients land in PENDING and require human review.

POST /dapp/clients — create a client

Submit a new client for KYC review. The Dr Green admin team reviews each client manually before they can transact.

Request body

The CreateClientDto is the input shape. Verified-required and most-common fields:

Canonical payload (for signing)

JSON.stringify(body) — compact, no whitespace.

Response

201 Created with the new client’s id in data. Detailed shape:

Errors


GET /dapp/clients — list clients

Paginated list of all clients owned by the current holder.

Query parameters

Canonical payload

urlencode(query) if any params present, else "{}".

Response shape (verified)

🪲 phoneCountryCode and phoneCode are different fields. phoneCountryCode is sometimes null while phoneCode ("+91") holds the dial prefix. Use phoneCode + contactNumber for E.164.
🪲 verifiedAt and rejectedAt appear in the list response but not in the detail response. If you need them, capture them at list time.

Worked example (Node)


GET /dapp/clients/list — unpaginated list

Same data as the paginated list but without pageMetaDto and without server-side limit. Use for <select> dropdowns where you need every client at once.

Canonical payload

{} (no query params).

Response

⚠️ Don’t use this for catalogue pages. It returns the full list and gets expensive at scale. Only use for autocomplete / picker UIs.

GET /dapp/clients/summary — status counts

Top-line counts for dashboards.

Canonical payload

{}

Response (verified)

The keys are the adminApproval values plus totalCount. Useful for a “tabs with counts” UI.

GET /dapp/clients/chart-data and /status-breakdown — time-series

Both endpoints require startDate and endDate query parameters. Without them you get a 400.

Required query parameters

Error if omitted (verified)

🪲 The error message has typo’d casing — it says “startdate” lowercase but the actual field is startDate. The validator will accept correctly-cased query params.

Canonical payload

startDate=2026-04-01&endDate=2026-05-01 🔒 Response shape for these is not yet captured live — pending a date-range probe. Update once verified.

GET /dapp/clients/{clientId} — full client detail

The complete record including shipping addresses, businesses, KYC, NFT linkage, and cart references.

Canonical payload

{}

Response shape (verified)

🪲 shippings and clientBusinesses are arrays — a client can have multiple. The order in the array is not guaranteed; sort/select by id or isPrimary when implementing.

PATCH /dapp/clients/{clientId} — update a client

Updates a subset of fields on an existing client.

Request body

Use UpdateClientDto. All fields are optional; only the ones you send will be updated:
To update shipping or business records, use the dedicated endpoints (TODO — UpdateShippingDto and UpdateClientBusinessDto flow not yet documented).

Canonical payload

JSON.stringify(body) — compact.

Response

200 OK with data.id of the updated client.

GET /dapp/client/{clientId}/orders — client’s orders

🪲 Note: path is /dapp/client/ (singular), not /dapp/clients/. Catch this in your routing.

Canonical payload

{} if no query, else urlencode(query). Supports page and limit.

Response

Same shape as GET /dapp/orders, but scoped to one client.

GET /dapp/client/{clientId}/transactions — client’s transactions

🪲 Same singular-path warning.

Response

Shape of each transaction record is not yet captured live. 🔒

Common patterns

Surfacing approval status to the customer

Polling for KYC completion

After a client submits, poll the detail endpoint every 5 minutes until isKYCVerified === true or adminApproval === 'REJECTED'. FirstAML verification timing varies by case complexity — straightforward cases complete in minutes, more involved AML reviews can take hours. Don’t poll faster than 5 minutes; it adds load without speeding anything up. See guides/kyc-flow.md for the full architecture.

Treating client identifiers

Always use the UUID id field server-side. Email is not unique across holders (different holders can have customers with the same email). Don’t use email as a primary key in your store DB.

See also