# Get hourly inbound Apple Messages for Business statistics

`GET /v1/amb/stats/inbound/hourly`

Returns one row of inbound Apple Messages for Business counts per hour, gap-filled so a silent hour is a zero row rather than a missing one. Every row is attributed to the hour the inbound event occurred, not to any earlier outbound message. Use it where the daily grain hides the shape; a window spans at most 720 hours (30 days), and for anything longer use the daily endpoint.

This channel has no delivery receipt and no derived rate; each row carries only the raw `received` count.

`from` and `to` are optional RFC 3339 instants, defaulting to the trailing 168 hours; each bound rounds down to the hour and remains inclusive. A request may span up to 30 days (720 rows). An excessive or reversed window returns `422`. Set `timezone` for local hours instead of UTC, including zones with sub-hour offsets; when the timezone's offset is not a whole number of hours, rows are read from finer-grained internal rollups and combined into hour boundaries automatically, with no parameter to select this. Historical dates are supported within the maximum window length; the requested dates are not shifted forward.

## Code samples

**TypeScript**

```ts
const result = await bird.amb.stats.inbound.hourly();
console.log(result);
```

Examples: [TypeScript](/docs/api/reference/get-amb-inbound-stats-hourly.ts.md) · [Python](/docs/api/reference/get-amb-inbound-stats-hourly.py.md) · [Go](/docs/api/reference/get-amb-inbound-stats-hourly.go.md) · [PHP](/docs/api/reference/get-amb-inbound-stats-hourly.php.md) · [CLI](/docs/api/reference/get-amb-inbound-stats-hourly.cli.md) · [MCP](/docs/api/reference/get-amb-inbound-stats-hourly.mcp.md) · [cURL](/docs/api/reference/get-amb-inbound-stats-hourly.curl.md)

## Example response `200`

```json
{
  "period": {
    "from": "2026-05-01",
    "to": "2026-05-25",
    "grain": "day",
    "data_as_of": "2026-05-25T14:03:10Z"
  },
  "attribution": "accepted_time",
  "data": [
    {
      "bucket": "2026-05-25",
      "received": 182
    }
  ]
}
```

## Query parameters

- `from` (string): Start of the window (RFC 3339 instant), rounded down to the start of its hour and included. The boundary uses the local hour when `timezone` is set and the UTC hour otherwise. The window may not exceed 30 days (720 hours). Defaults to 168 hours (7 days) before `to` when omitted.
- `to` (string): End of the window (RFC 3339 instant), rounded down to the start of its hour and included. The boundary uses the local hour when `timezone` is set and the UTC hour otherwise, so both bounds are inclusive. The window may not exceed 30 days (720 hours). Defaults to the current hour when omitted.
- `timezone` (string): IANA timezone identifier used to group statistics, for example `Asia/Kathmandu`. The default is UTC. Day and hour boundaries, including the default window when `from` and `to` are omitted, follow this timezone. When this parameter is set, pass `from` and `to` as calendar days or `Z` instants instead of timestamps with explicit UTC offsets.

## Response body

- `period` (object, required): The window and bucket grain the response covers, echoed from the request, plus the freshness boundary the data is current to.
- `period.from` (string, required): Inclusive start of the window. A calendar day (YYYY-MM-DD) on the day grain, an RFC 3339 instant on the hour grain. Historical starts are preserved; the maximum request length does not impose a historical cutoff.
- `period.to` (string, required): Inclusive end of the window. A calendar day (YYYY-MM-DD) on the day grain, an RFC 3339 instant on the hour grain.
- `period.grain` (string, required)

  The bucket grain of the series, either `day` or `hour`.

  Possible values: `day`, `hour`
- `period.data_as_of` (nullable string): Latest time reflected in the statistics. More recent events might not be included yet. Null when the freshness boundary is unavailable.
- `attribution` (string, required)

  Always `event_time` for inbound statistics.

  Possible values: `accepted_time`, `event_time`
- `data` (array of object, required): One row per bucket (day or hour, matching the request) in the period, in chronological order. Buckets with no activity are included with a count of zero, so the series charts continuously without client-side gap handling.
- `data.bucket` (string, required): The day (YYYY-MM-DD) or hour (RFC 3339, on the hour) this point covers, matching the request's grain.
- `data.received` (integer, required): Distinct messages received in this bucket.

## Related resources

- [Should I use a Bird SDK or call the API directly?](/explained/platform/should-i-use-an-sdk-or-call-the-api-directly) (answer)
- [Build your first integration](/learn/paths/integration) (course)
- [Send your first email](/docs/get-started/send-your-first-email) (docs)

[Get an implementation brief](/learn/workspace?topic=api-basics)
