Volume Trends (report)

GET/api/v1/reports/volume-trends
Requires anorganization API keywith the scopereports:read

Request

GET/api/v1/reports/volume-trends
curl -X GET 'https://app.mailyte.com/api/v1/reports/volume-trends' \
  -H 'Authorization: Bearer mk_live_YOUR_API_KEY'
The key names its own organization, so no X-Organization-ID header is needed.

Response

Success.

  • dataobject
    • objectstringvolume_report
    • generated_atstring

      When this response was computed, ISO 8601 UTC. Every report answers it, so "is this figure stale?" never depends on which report you asked.

    • periodobject

      The window this report actually covers, which is not always the window you asked for: a `date_range` outside `day`, `week`, `month` and `quarter` is silently replaced with `month`, so a request for `year` returns thirty days and this object is the only place that says so. Null when the report covers no window -- a stored result read back from `/reports/history` keeps no record of the window it was built over, and inventing one from your current query would describe the query rather than the data.

      • start_atstring
      • end_atstring
      • granularitystringday

        The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored.

    • totalsobject

      The top-line counts. `average_daily_volume` and `peak_volume` are gone: both were one line of caller code over `series`, and both were computed from `events`, which is not a message count.

      • eventsinteger

        Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero.

      • sentinteger

        In THIS report only, `sent` is `delivered + bounced` -- the messages that reached a receiving server and got a verdict. `/reports/email-delivery` publishes `sent` as five event types (deferrals, rejections and drops as well), so the same name returns a different and smaller number here. Do not compare the two directly. Recorded as a defect in plans/13-public-api-contract/converted/mailserver.md; the counts are published as the service computes them rather than quietly reconciled. Summed from `series`, so the two can never drift apart.

      • receivedinteger

        Inbound mail (`email.inbound`). Summed from `series`.

    • seriesarray<object>

      The same counts bucketed over the period, oldest first. Rows are SPARSE: a bucket in which nothing happened has no row at all, rather than a row of zeros, so do not index this array by day offset.

      • start_atstring

        The instant this bucket opens, midnight UTC. Replaces the bare `2026-09-17` these rows used to carry, which named no timezone. NULL MEANS UNKNOWN -- we could not read this bucket's boundary -- and never that the bucket has no start or is empty. A LIVE report cannot produce it: the rows are grouped by `delivery_events.created_at`, which is NOT NULL, so every bucket is keyed by a real date. It is reachable only through `GET /reports/history`, where the row is JSON written by whichever version of the report ran at the time and re-rendered through this same resource WITHOUT being re-validated; a stored row carrying no date becomes null here rather than being silently dated today. Drop such a row or read the report live.

      • eventsinteger

        Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero.

      • sentinteger

        In THIS report only, `sent` is `delivered + bounced` -- the messages that reached a receiving server and got a verdict. `/reports/email-delivery` publishes `sent` as five event types (deferrals, rejections and drops as well), so the same name returns a different and smaller number here. Do not compare the two directly. Recorded as a defect in plans/13-public-api-contract/converted/mailserver.md; the counts are published as the service computes them rather than quietly reconciled. Null means the figure is unavailable, never that it is zero.

      • receivedinteger

        Inbound mail (`email.inbound`). Null means the figure is unavailable, never that it is zero.

    • distributionsobject

      Histograms, not time series, which is why they are not `series`. TWO CAVEATS, both unchanged behaviour: the buckets are SPARSE -- an hour or a weekday with no events has no row rather than a zero -- and they are cut on the SERVER's application timezone, not yours and not UTC, so a bucket label is only meaningful once you know that timezone. The `percentage` each row used to carry is gone; it duplicated `events` over `totals.events`.

      • hour_of_dayarray<object>
        • bucketstring

          `"00"` to `"23"`.

        • eventsinteger

          Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero.

      • day_of_weekarray<object>
        • bucketstring

          `"Monday"` to `"Sunday"`, in English.

        • eventsinteger

          Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero.

Returned inside the standard envelope.

Errors

StatusWhen
401The API key is missing, unknown, revoked or expired. All four answer identically, on purpose: distinguishing them would confirm which keys exist.
403The key is valid but may not do this: it lacks the required scope, its IP allowlist does not include you, or this endpoint does not accept API keys.
404No such resource in this organization.
422The request was understood but the values were not acceptable.
429Too many requests, or the organization has spent its sending allowance. `Retry-After` says how long to wait.

Every status, with what causes it and what to do, is on the error reference.