Skip to content

Scheduling

Scheduling pins a post to one or many future timestamps. The composer offers manual entry plus a Find slot button backed by your channel's engagement history.

time_posts

time_posts is an array of ISO-8601 timestamps. With post_by: 1 (schedule) or post_by: 2 (specific days/times) the array holds the schedule for each leg of the multi-channel fan-out — one entry per leg.

Constraints:

  • All entries must be at least 1 minute in the future.
  • ISO-8601 strings are always interpreted as UTC; channel-local times are converted client-side before submission.

Find slot

GET /api/v1/posts/find-slot?accounts=<id1>,<id2>&count=<1-10>

Returns up to count (default 3) suggested slots in the response shape:

json
{
  "slots": [
    { "iso": "2026-05-04T13:00:00.000Z", "hour": 13, "weekday": 1, "score": 18.4, "source": "engagement" }
  ]
}

How slots are picked (from backend/src/services/findSlot.service.ts):

  1. Query PostStats for the supplied accounts over a 90-day window.
  2. Aggregate by UTC hour × weekday, computing average engagement (likes + comments + shares + scaled engagement-rate).
  3. Return the top-count distinct (hour, weekday) combinations.
  4. If the engagement signal is too thin, fall back to default UTC hours 9, 13, 19 with source: "default".

Timezone handling

Internal storage and find-slot calculations are in UTC. Per-account timezones are not yet wired into find-slot; channel-local display in the calendar UI is a frontend concern. The recurrence model includes a timezone field defaulted to Europe/Istanbul for future use.

Recurrence (planned)

The post model supports a recurrence block:

typescript
recurrence?: {
  rrule: string;     // RFC 5545 rrule
  until?: Date;
  count?: number;
  timezone?: string; // default "Europe/Istanbul"
}

Storage and reads are in place but no UI surface enables recurrence today. Treat it as upcoming; users currently schedule individual time_posts instead.