It's built and pushed. Function, call example, then three things you need to know before you wire it. * The call (cj/agenda-window-json START-EPOCH END-EPOCH &optional OUT-PATH) From a shell: emacsclient --eval '(cj/agenda-window-json 1785474000 1785560399 "/tmp/agenda.json")' Both bounds are epoch seconds, inclusive. It returns the JSON string and, with OUT-PATH, also writes it there through a temp file and a rename. The file lands 0644 so a reader running as anyone can open it. Per row: title, start, end, all-day, type, file, keyword, done, repeater, location, organizer. Absent values are null rather than omitted, so the shape is stable. Verified against my real agenda: 13 rows today, sorted by start, both calendars and both todo files, no Emacs buffer left modified. * The repeater premise was wrong, and the real gap is bigger You cited "Sched. 19x:" as evidence of repeating entries. That is org-agenda-scheduled-leaders, and the number counts days an unfinished scheduled item has been carried forward. It is not a repeater. My agenda files contain zero repeating timestamps right now. Your instinct was right anyway, and it points at something worse than the case you asked about. I have 18 undone scheduled items dated before today. Org shows every one of them on today's agenda, because that is what carrying forward means. A query that selects on timestamps inside the window cannot see them. So today my agenda has about 31 items and this query returns 13. Deadlines do the same thing in the other direction: org surfaces a deadline up to 14 days before its date, and the query only returns it on the day itself. I have not guessed at what you want here, because it is a real design question for your surface rather than a bug. A 24-hour axis has nowhere obvious to draw "overdue since the 12th." Three options, roughly: leave it (a timed-events surface, which is defensible), add an overdue flag and let you decide where they go, or pin them to the window start. Tell me which and I will build it. * The .+ field is not there, and I think it should not be You asked for the fallback mark as a testable field. I did not add it, because the state it marks cannot occur, and I would rather tell you than ship a field that is permanently false. Org's own org-closest-date matches the repeater with a regexp that ignores the prefix entirely, so .+ and ++ expand from the base exactly like +. The restart semantics happen at completion time: org rewrites the base timestamp in the file when you close the task. So for an open task the base already is the last repeat, and there is nothing unresolved to mark. You said to tell you rather than guess, so this is me telling you. If you still want the field for defensive reasons, say so and it is a one-line addition. * Smaller things worth knowing Repeats resolve at day granularity, matching org's agenda, so an hourly repeater gives one row per day rather than one per hour. Archived and commented subtrees are skipped, because org's agenda skips them. Titles render org links as their description text. One of my live entries is a captured web item, and it would otherwise arrive as [[https://...][Tracking your habits]] on your wallpaper. The window is capped at 366 days, and each bound must fall between 1900 and 2200. Both checks exist for one reason: Date.now() returns milliseconds. Passing it for both bounds looks like a plausible 41-day window and answers with dates in the year 58549, so magnitude is checked as well as width. * On the tests 58 of them, across three files. The SCHEDULED one you asked for is there, and its fixture carries no body timestamp on purpose, so an implementation that drops planning timestamps fails it rather than passing on the body stamp. The trap earned its comment in the source, as you suggested.