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

# Dashboard

# Dashboard

> **Endpoint reference: ✅ Verified live against production on 10 May 2026.**
> Two endpoints power the holder's headline dashboard: a static counter snapshot, and a date-ranged time-series for charts.

***

## Endpoints

| Method | Path                        | Auth          | Description                                     |
| ------ | --------------------------- | ------------- | ----------------------------------------------- |
| `GET`  | `/dapp/dashboard/summary`   | API-key + sig | Counters: clients, orders, products, profit     |
| `GET`  | `/dapp/dashboard/analytics` | API-key + sig | Time-series for one of: Client / Order / Profit |

***

## `GET /dapp/dashboard/summary` — counter snapshot

The headline numbers for a holder's home page. Cheap call, no params.

### Canonical payload

`{}`

### Response shape (verified)

```json theme={null}
{
  "success": true,
  "statusCode": 200,
  "message": "Success",
  "data": {
    "clientCount": 19,
    "orderCount": 21,
    "productCount": 210,
    "estimateProfit": 157.13,
    "totalProfit": 157.13,
    "profitRecieved": 0
  }
}
```

| Field            | Type         | Meaning                                                     |
| ---------------- | ------------ | ----------------------------------------------------------- |
| `clientCount`    | int          | Total clients owned by this holder, all statuses            |
| `orderCount`     | int          | Total orders placed against this holder, all statuses       |
| `productCount`   | int          | Strain catalogue size for the holder's region               |
| `estimateProfit` | number (USD) | Lifetime profit estimate including pending                  |
| `totalProfit`    | number (USD) | Lifetime profit accrued                                     |
| `profitRecieved` | number (USD) | **Profit actually paid out** *(typo preserved — see below)* |

> ⚠️ **`profitRecieved` is misspelled in the API.** It's missing the second `e` — should be `profitReceived` but the production API returns `profitRecieved`. **Do not auto-correct in your code** or you'll silently get `undefined`. Document the field as-is in your TypeScript types:
>
> ```ts theme={null}
> interface DashboardSummary {
>   clientCount: number;
>   orderCount: number;
>   productCount: number;
>   estimateProfit: number;
>   totalProfit: number;
>   profitRecieved: number;  // sic — misspelled in API
> }
> ```

> 🪲 **`estimateProfit` and `totalProfit` are equal** in the verified data. Backend likely treats them as separate concepts (e.g. estimate includes deductions / pending) but the values match in practice. Use `totalProfit` for display.

> 🪲 **`profitRecieved: 0`** when no payouts have occurred. Use this to show "X% of your earnings paid out" — `(profitRecieved / totalProfit) * 100`.

### Worked example (Python)

```python theme={null}
def dashboard_widget():
    payload = canonical_payload("GET")
    headers = auth_headers(API_KEY, SECRET_KEY, payload)
    r = httpx.get("https://api.drgreennft.com/api/v1/dapp/dashboard/summary", headers=headers)
    r.raise_for_status()
    s = r.json()["data"]
    return {
        "clients": s["clientCount"],
        "orders": s["orderCount"],
        "products": s["productCount"],
        "lifetime_profit_usd": s["totalProfit"],
        "paid_out_usd": s["profitRecieved"],  # sic
        "outstanding_usd": s["totalProfit"] - s["profitRecieved"],
    }
```

***

## `GET /dapp/dashboard/analytics` — time-series

Returns a `[{name, value, date}]` array suitable for a line or bar chart. Choose what to plot via `filterBy`.

### Required query parameters

| Name        | Type   | Format                | Notes                                                                                                                      |
| ----------- | ------ | --------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `startDate` | string | **ISO 8601** datetime | E.g. `2026-04-10T00:00:00.000Z` — note this is **not** the same format as the other chart endpoints which use `YYYY-MM-DD` |
| `endDate`   | string | **ISO 8601** datetime | E.g. `2026-05-10T23:59:59.999Z`                                                                                            |
| `filterBy`  | string | Enum                  | One of: `Client`, `Order`, `Profit` (case-sensitive)                                                                       |

> 🪲 **Date format mismatch.** This endpoint requires ISO 8601 (`YYYY-MM-DDTHH:mm:ss.sssZ`); the chart endpoints on individual resources (`/dapp/orders/chart-data` etc.) use plain `YYYY-MM-DD`. Two formats in the same API. Mind it.

### Error if missing or wrong (verified)

```json theme={null}
{
  "statusCode": 400,
  "message": "startDate must be a valid ISO 8601 date string, startDate should not be empty, endDate must be a valid ISO 8601 date string, endDate should not be empty, filterBy must be one of the following values: Client, Order, Profit, filterBy should not be empty, filterBy must be a string"
}
```

### Canonical payload

`urlencode(query)` — e.g. `startDate=2026-04-10T00:00:00.000Z&endDate=2026-05-10T23:59:59.999Z&filterBy=Order`

### Response shape (verified)

A flat array, **no envelope wrapper** at the data level — `data` is the array itself, not `{ analytics: [...] }`.

```json theme={null}
{
  "success": true,
  "statusCode": 200,
  "message": "Success",
  "data": [
    {
      "name": "Friday",
      "value": 1,
      "date": "2026-04-24T00:00:00.000Z"
    }
  ]
}
```

| Field   | Type              | Notes                                        |
| ------- | ----------------- | -------------------------------------------- |
| `name`  | string            | Day-of-week label (`Monday`, `Tuesday`, ...) |
| `value` | number            | Count or amount, depending on `filterBy`     |
| `date`  | string (ISO 8601) | The day this bucket represents               |

For `filterBy=Profit`, `value` is in USD (e.g. `66` = \$66 profit on that day).
For `filterBy=Client`, `value` is the count of clients created that day.
For `filterBy=Order`, `value` is the count of orders placed that day.

> 🪲 **`name` is the weekday name, not the date.** If your chart spans more than 7 days, you'll see repeated names (`Monday`, `Monday`, `Monday`). Always use `date` for the X-axis, not `name`. `name` is presumably for a "this week" view but isn't very useful otherwise.

> ⚠️ **Empty days are not returned.** If no clients/orders/profit on a day, that day is missing from the array. To render a continuous chart, fill gaps client-side:
>
> ```ts theme={null}
> function fillGaps(start: Date, end: Date, points: AnalyticsPoint[]): AnalyticsPoint[] {
>   const byDate = new Map(points.map(p => [p.date.slice(0, 10), p]));
>   const out: AnalyticsPoint[] = [];
>   for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
>     const key = d.toISOString().slice(0, 10);
>     out.push(byDate.get(key) ?? {
>       name: d.toLocaleDateString('en-US', { weekday: 'long' }),
>       value: 0,
>       date: d.toISOString(),
>     });
>   }
>   return out;
> }
> ```

### Worked example (cURL)

```bash theme={null}
QUERY='startDate=2026-04-10T00:00:00.000Z&endDate=2026-05-10T23:59:59.999Z&filterBy=Order'
SIG=$(printf '%s' "$QUERY" | openssl dgst -sha256 -sign ~/.drgreen/secret.pem | base64 -w0)
curl "https://api.drgreennft.com/api/v1/dapp/dashboard/analytics?$QUERY" \
  -H "x-auth-apikey: $DRGREEN_API_KEY_B64" \
  -H "x-auth-signature: $SIG"
```

***

## Common patterns

### Holder's home dashboard

Combine the summary endpoint with a 30-day analytics chart:

```ts theme={null}
async function homeDashboard() {
  const end = new Date();
  const start = new Date(end.getTime() - 30 * 24 * 60 * 60 * 1000);
  const [summary, orders, profit] = await Promise.all([
    getDashboardSummary(),
    getDashboardAnalytics(start, end, 'Order'),
    getDashboardAnalytics(start, end, 'Profit'),
  ]);
  return {
    headline: summary,
    orderTrend: fillGaps(start, end, orders),
    profitTrend: fillGaps(start, end, profit),
  };
}
```

### Don't render `profitRecieved` in account ledgers

It's a snapshot of cumulative payouts, not a transaction list. For an actual ledger, use `/dapp/commissions?paymentStatus=PAID`.

***

## Caching guidance

| Endpoint  | TTL                                       |
| --------- | ----------------------------------------- |
| Summary   | 1 minute                                  |
| Analytics | 5 minutes (per-`filterBy` per-date-range) |

***

## See also

* [Commissions](./commissions.md) — payout detail behind `profitRecieved`
* [Orders](./orders.md) — driver of `orderCount` and `totalProfit`
* [Clients](./clients.md) — driver of `clientCount`
