Skip to main content

SuggestionEvent

One source event to create or update.

The write shape is flat: fields that come back nested under properties are sent at the top level. Send id_project, not properties.id_project.

Two things are required of every event, on create and on update alike:

  1. Something to read. At least one of comment, title, subject, or body. This is the text the engine predicts entry codes from; without it there is nothing to work with.
  2. A start and an end. One of these pairs: start_datetime + end_datetime, start_isodatetime + end_isodatetime, start_timestamp + end_timestamp, or record_date + record_date_end. date_f8 alone stands in for the last pair when the event covers a single day.

The dates are required on update as well, which is easy to trip over: every write re-runs the event through the same intake path a calendar feed uses, and intake reads the dates each time. An update that omits them is rejected with a 400 even though the stored suggestion already has them.

Fields the engine owns cannot be supplied. Sending one is a 400 naming it, rather than a silent drop, so a client learns its write did not take. Those are: id_suggestion (except as the URL's own ID on a PUT), source_category, state, properties, source_data, the audit fields (creator, create_timestamp, modifier, modify_timestamp), the id_time_rec / id_expense_rec / id_travel_rec links, match_code, match_description, and every *_predict name. To pin a value, drop the _predict suffix: send id_project, not id_project_predict.

Any field not listed here that the Suggestion Engine recognizes is accepted and stored; unrecognized fields are ignored.

source_idstring

Your stable identifier for this event, and the key POST upserts on. See source_id on the Suggestion schema.

Example: jxfeed-alice-20260914-a91c3f
id_userstring

Whose Suggested Entries this belongs to. Defaults to the authenticated user. Naming someone else requires a timekeeping ability over that user; without it the request is refused with a 403.

On a PUT, this may only repeat the suggestion's current owner. A suggestion cannot be moved between users.

Example: alice
subjectstring

The event's title. One of subject, title, comment, or body is required. Whichever you send is stored as the suggestion's comment.

Example: Sprint planning with the platform team
titlestring

An alternative to subject.

commentstring

The text to use directly, when your source has no separate subject.

Example: Sprint planning with the platform team
bodystring

Longer event text — a meeting body, a description. Used for prediction when no shorter text is available, and read by the user's auto-hide phrase rules either way.

start_datetimestring

When the event starts. An ISO 8601 string; include the UTC offset or zone so the value is unambiguous. Paired with end_datetime.

Example: 2026-09-14T09:00:00-05:00
end_datetimestring

When the event ends. Paired with start_datetime.

Example: 2026-09-14T10:30:00-05:00
start_isodatetimestring

An alternative spelling of start_datetime, paired with end_isodatetime.

end_isodatetimestring

Paired with start_isodatetime.

start_timestampnumber

The start as a UTC epoch timestamp, paired with end_timestamp. Use this when your source has no zone information to offer.

Example: 1789736400
end_timestampnumber

The end as a UTC epoch timestamp.

Example: 1789741800
record_datestring

The first date the event covers, as YYYYMMDD. Paired with record_date_end. The coarsest of the four date forms: it fixes the days but not the times.

Example: 20260914
record_date_endstring

The last date covered, as YYYYMMDD. Same as record_date for a single-day event.

Example: 20260914
date_f8string

Shorthand for a single-day event: sets both record_date and record_date_end.

Example: 20260914
is_all_dayboolean

True for an all-day event with no meaningful clock time.

Example: false
series_idstring

The recurring series this occurrence belongs to. Send the same value on every occurrence of a series, and the engine can carry an accepted choice forward to later occurrences — and the series dismiss action can act on the whole series at once.

Example: AAMkAGI2-recurring-standup
id_projectstring

Pin the project rather than letting the engine predict it. Use this when your source already knows the answer — a ticketing integration that maps a project of its own onto a Journyx project, for example.

Pinning still leaves the engine's guesses in place under properties.id_project_predict, so the two can be compared.

Example: 8A2F4B3D5E6C7891A2B3C4D5E6F78901
id_code_taskstring

Pin the task code. Behaves like id_project.

id_code_pay_typestring

Pin the pay type.

id_code_bill_typestring

Pin the bill type.

id_groupstring

Pin the group.

time_amountnumber

Hours to suggest. Omit it and the entry screen derives the duration from the start and end.

Example: 1.5
occurrencesarray[]

For a recurring event, the [start_datetime, end_datetime] pairs of each occurrence in the period. The rest of the event describes the first one.

SuggestionEvent
{
"source_id": "jxfeed-alice-20260914-a91c3f",
"id_user": "alice",
"subject": "Sprint planning with the platform team",
"title": "string",
"comment": "Sprint planning with the platform team",
"body": "string",
"start_datetime": "2026-09-14T09:00:00-05:00",
"end_datetime": "2026-09-14T10:30:00-05:00",
"start_isodatetime": "string",
"end_isodatetime": "string",
"start_timestamp": 1789736400,
"end_timestamp": 1789741800,
"record_date": "20260914",
"record_date_end": "20260914",
"date_f8": "20260914",
"is_all_day": false,
"series_id": "AAMkAGI2-recurring-standup",
"id_project": "8A2F4B3D5E6C7891A2B3C4D5E6F78901",
"id_code_task": "string",
"id_code_pay_type": "string",
"id_code_bill_type": "string",
"id_group": "string",
"time_amount": 1.5,
"occurrences": [
"string"
]
}