Skip to main content

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.

Revenue

Endpoint reference: ✅ Verified live against production on 10 May 2026. Revenue endpoints surface the holder’s earnings from a product-level view — what each strain has sold and earned. Distinct from Commissions (per-order earnings) and Dashboard (top-line aggregates).

Endpoints

MethodPathAuthDescription
GET/dapp/revenueAPI-key + sigRevenue per strain, paginated
GET/dapp/revenue/summaryAPI-key + sigAggregate sales and profit
GET/dapp/revenue/chart-dataAPI-key + sigTime-series for revenue charts

GET /dapp/revenue — revenue per strain

Returns each strain along with its sales totals over the holder’s lifetime. Useful for “top sellers” tables.

Query parameters

NameTypeDefaultNotes
pageinteger1
limitinteger10
sortBystringLikely totalRevenue, totalQuantity (verify with backend)
orderstringasc or desc

Canonical payload

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

Response shape (verified)

{
  "success": true,
  "statusCode": 200,
  "message": "Success",
  "data": {
    "strains": [
      {
        "strainId": "c0a31701-a2b5-42c0-8ed2-59636e981338",
        "strainName": "Peanut Butter Breath",
        "wholeSalePrice": 6,
        "retailPrice": 10,
        "totalQuantity": 5,
        "totalSales": 50,
        "totalRevenue": 50
      }
    ],
    "pageMetaDto": {
      "page": "1", "take": 10, "itemCount": 2,
      "pageCount": 1, "hasPreviousPage": false, "hasNextPage": false
    }
  }
}
FieldTypeNotes
strainIdstring (UUID)Cross-reference to Strains
strainNamestringDenormalised strain name (snapshot at sale time)
wholeSalePricenumber (USD)Per-unit wholesale (current value)
retailPricenumber (USD)Per-unit retail (current value)
totalQuantityintTotal units (grams) sold of this strain
totalSalesnumber (USD)Total revenue (totalQuantity * retailPrice typically)
totalRevenuenumber (USD)Same as totalSales in observed data
🪲 totalSales and totalRevenue are equal in the verified data — duplicate fields. Pick one.
🪲 The wrapper field is strains, not revenue — consistent with the Strains endpoint but a slightly odd choice given this endpoint is /revenue/. Cross-link via strainId.
⚠️ wholeSalePrice and retailPrice are the current prices, not the price at which historical sales occurred. If Dr Green changes a strain’s price, this endpoint will show the new price even for old sales. For an accurate per-sale price, use Orders which captures the price snapshot.

Worked example (Node)

async function topSellers(limit = 5) {
  const q = { page: '1', limit: String(limit), sortBy: 'totalRevenue', order: 'desc' };
  const payload = canonicalPayload('GET', null, q);
  const headers = authHeaders(API_KEY, SECRET_KEY, payload);
  const url = new URL('https://api.drgreennft.com/api/v1/dapp/revenue');
  Object.entries(q).forEach(([k, v]) => url.searchParams.set(k, v));
  const res = await fetch(url, { headers });
  return (await res.json()).data.strains;
}

GET /dapp/revenue/summary — aggregate

The headline numbers across all strains.

Canonical payload

{}

Response shape (verified)

{
  "success": true,
  "statusCode": 200,
  "message": "Success",
  "data": {
    "summary": {
      "totalSales": 70,
      "totalProfit": 70
    }
  }
}
🪲 totalSales and totalProfit are equal in observed data70 and 70. This is unexpected; profit should be sales minus wholesale cost. Likely a backend issue or an interpretation difference. Don’t trust totalProfit from this endpoint — cross-check against dashboard/summary.totalProfit. 🔒 Flag for backend confirmation.

GET /dapp/revenue/chart-data — time-series

For plotting revenue over a date range.

Required query parameters

NameTypeFormatNotes
startDatestringYYYY-MM-DDInclusive
endDatestringYYYY-MM-DDInclusive
If omitted, returns 400:
{
  "statusCode": 400,
  "message": "startdate must be a valid date. ex: YYYY-MM-DD or MM-DD-YYYY, startDate should not be empty, ..."
}

Canonical payload

startDate=2026-04-10&endDate=2026-05-10

Response shape (verified, but empty for the test holder)

{
  "success": true,
  "statusCode": 200,
  "message": "Success",
  "data": []
}
🔒 Shape with populated data not yet captured — the test holder had no revenue in the probe window. Based on the parallel /orders/chart-data shape (which uses the same response format), expect:
{
  "data": [
    { "name": "Friday", "value": 50, "date": "2026-04-24T00:00:00.000Z" }
  ]
}
Where value is the day’s revenue in USD. Defensively handle the empty array — if no data in the window, the array is empty (not absent or null).
🪲 Same gap-filling caveat as dashboard analytics — empty days are not returned. Fill in the client to render a continuous chart. See Dashboard § Empty days for the helper function.

Common patterns

Top-sellers leaderboard

async function topSellersWidget() {
  const top = await topSellers(5);
  return top.map(s => ({
    name: s.strainName,
    units: s.totalQuantity,
    revenue: s.totalRevenue,
    avgPrice: s.totalQuantity > 0 ? s.totalRevenue / s.totalQuantity : 0,
  }));
}

Monthly revenue trend

import datetime as dt

async def monthly_trend(months_back: int = 6):
    end = dt.date.today()
    start = end - dt.timedelta(days=months_back * 30)
    q = {"startDate": start.isoformat(), "endDate": end.isoformat()}
    payload = canonical_payload("GET", query=q)
    headers = auth_headers(API_KEY, SECRET_KEY, payload)
    url = f"https://api.drgreennft.com/api/v1/dapp/revenue/chart-data?{urlencode(q)}"
    r = httpx.get(url, headers=headers)
    return r.json()["data"]  # [{name, value, date}]

Reconciliation note

Three endpoints surface “profit”-shaped numbers:
SourceFieldWhat it actually is
/dapp/dashboard/summarytotalProfitLifetime profit (USD)
/dapp/revenue/summarytotalProfitSame number, but sometimes equals totalSales ⚠️
/dapp/commissions/summarycommissionSummary.totalInDollarSum of all commission records (delivered orders only)
Use dashboard.totalProfit as the canonical “lifetime earnings” figure. The other two are useful for breakdowns but should reconcile back to it (within rounding).

Caching guidance

EndpointTTL
Revenue list5m
Revenue summary5m
Revenue chart-data5m per date range

See also

  • StrainsstrainId cross-reference
  • Orders — orders capture per-sale price snapshots
  • Commissions — per-order payout view
  • Dashboard — canonical lifetime profit figure