> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/sdgm/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/sdgm/_mcp/server.

# First Open Hour Prediction

A notification team wants to understand when each client is likely to engage before planning its next campaign. This example predicts the hour of a client's first recorded notification open over the next day, assuming the client opens at least one notification in that period. Kumo Engine learns from clients and their connected open history to classify that first open into an hour of the day. The predicted hour gives the team a planning signal to evaluate alongside its sending rules and campaign experiments.

## Data and relationships

The example assumes a prepared Kumo Engine `graph`, a matching `snapshot`, and these tables:

| Table     | Required columns                                                                  | Purpose                                                                                                                                        |
| --------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `clients` | `client_id` as the primary key                                                    | The clients to score. Optional profile columns can describe each client.                                                                       |
| `opens`   | `open_id` as the primary key, plus `client_id`, `open_timestamp`, and `open_hour` | One row per recorded notification open. `open_hour` is the UTC hour of `open_timestamp`, stored as a categorical string from `"00"` to `"23"`. |

Connect `opens.client_id` directly to `clients.client_id`. Mark `open_timestamp` as the time column of the opens table and `open_hour` as categorical, so the target predicts an hour category. Prepare the hour column from each open timestamp in UTC before creating the graph, and keep the timestamp and hour in the same timezone. Include only the notification types you want this prediction to describe.

The `clients` table has no time column of its own, so the one-day window starts at the scoring time. It excludes opens at that exact time and includes opens through 24 hours later. For example, a prediction made at noon looks through noon the next day, rather than stopping at midnight.

## Predict the first open hour over the next day

`FIRST(opens.open_hour, 0, 1, days)` selects the hour recorded on the earliest open by timestamp in the next day. If a client first opens at 20:00 and opens twice more at 02:00 the following morning, the target is `"20"`. It is the first observed hour in the window, rather than the most frequent hour or the lowest hour number.

```python
from kumo.engine import PredictiveQuery

query_text = (
    "PREDICT FIRST(opens.open_hour, 0, 1, days) "
    "FOR EACH clients.client_id "
    "ASSUMING COUNT(opens.*, 0, 1, days) > 0"
)
query = PredictiveQuery(graph, query_text)
query.validate()
print(query.get_task_type())  # multiclass_classification
```

The `ASSUMING` clause makes this a conditional prediction: historical client windows with no opens do not supply training labels. It does not predict whether a client will open a notification, and it does not remove clients with no future opens from the scoring population. Each scored client receives an estimate of the first open hour under the stated assumption.

## Reading the predictions

The prediction assigns probabilities to hour categories for each client. A higher probability for `"20"` means a stronger expectation that the client's first open in the next 24 hours will occur during the UTC hour starting at 20:00, conditional on an open occurring. It is not a probability of opening a message sent at 20:00.

Use the hour estimate to form engagement segments or candidate scheduling rules that you evaluate in a campaign experiment. This query has no candidate send time or campaign in its prediction entity, so it does not compare send times, establish an optimal sending hour, or estimate how changing the send time would change engagement. Keep that distinction when turning observed opening patterns into a notification plan.