When to use this endpoint

Use booked=1 for the current CRM2 My Booked Webinars screen. Omit booked only when intentionally reading legacy interests; the two modes represent separate data and are not interchangeable confirmation lists.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. Every Training handler requires login; there is no additional page, role, department, or tenant feature-flag check. CRM2 exposes Training to authenticated users.

Webinars and session IDs belong to a shared global catalogue. Interests and provider registrations are scoped to the authenticated tenant and user even though they are stored globally. Client-supplied tenant/user IDs do not select another person’s bookings or progress.

Parameters

ParameterTypeRequiredDescription
bookedPHP truthy flagNoDefault false selects active local interests. Any PHP-nonempty value selects provider bookings: 1 works, string "0"/blank are false, but string "false" is true. This is not strict boolean-string parsing.

Example request

$result = FM_api('Training_mySessions', [
	'booked' => '1',
]);

Example response

{
  "data": [
    {
      "id": 1042,
      "webinar_id": 91,
      "title": "Jobs from start to finish",
      "description": "Create and schedule jobs with Fieldmotion.",
      "category": "jobs",
      "category_name": "Jobs",
      "image_url": "https://example.test/training.webp",
      "image_alt": "Fieldmotion Training",
      "presenter": "Fieldmotion trainer",
      "starts_at": 1794477600,
      "ends_at": 1794481200,
      "timezone": "Europe/Dublin",
      "status": "scheduled",
      "capacity": null,
      "registration_closes_at": 0,
      "registration_open": true,
      "registration_url": "",
      "interested": false,
      "registration_opened_at": 0,
      "join_available": false,
      "join_url": "",
      "registration_state": "confirmed",
      "provider_mapped": true,
      "provider_available": true,
      "recording_provider_mapped": false,
      "recording_registration_state": "none",
      "recording_duration": 0,
      "watched_seconds": 0,
      "recording_available": false,
      "recording_url": "",
      "recording_published_at": 0
    }
  ],
  "stale": false,
  "unavailable": false
}

Each session object includes integer id/webinar_id, Unix-second starts_at/ends_at, stored timezone, title/description/category/category_name, image_url/image_alt/presenter, session status, nullable capacity and integer registration_closes_at. Unknown category values normalize to general. Descriptions are returned as text values without HTML sanitization; render them as text, as CRM2 does.

Action/state fields are registration_open, registration_url, interested, registration_opened_at, join_available, join_url, registration_state, provider_mapped, provider_available, recording_provider_mapped, recording_registration_state, recording_duration, watched_seconds, recording_available, recording_url and recording_published_at. Flags are booleans, durations/times/counts are integers, and URL/state fields are strings. Unavailable URLs are empty strings, not omitted.

A provider-mapped live session requires cached registration_state=confirmed for joining; a legacy unmapped session requires local interested=true. The session must be scheduled, current time must be at least starts_at−900 and no later than ends_at, and the chosen personal/legacy join URL must be valid HTTPS without embedded credentials. Joining is not exposed earlier by get/list.

Recordings require completed session status, published recording status, and ends_at no later than now. Mapped recordings expose no shared recording_url: use Training_watch for personal access. Unmapped recordings expose a valid HTTPS URL. A recording can be available without live interest or a live booking. Images also require valid HTTPS without embedded credentials.

Both modes return data with normalized session objects, capped at 200, with no count, categories or pagination cursor. booked=1 adds stale/unavailable flags. The example is a confirmed mapped booking before its join window.

Errors and unusual responses

ResponseCondition
{"error":"not logged in"}No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • Default mode requires active=1 on the authenticated user’s interest row, a published parent webinar and ends_at later than now−90×86400. It can include cancelled or completed sessions in that recent-history window; there is no independent session-status filter.
  • Booked mode requires provider schema, cached registration state confirmed or pending, scheduled status and ends_at > now. Already-started but not-ended sessions remain eligible. A provider booking can appear without a legacy interest, and a legacy interest alone does not appear as a booking.
  • If provider schema is unavailable, booked mode deliberately returns an empty list with stale=true/unavailable=true, rather than reinterpreting interests as bookings.
  • Order places not-yet-ended sessions first by starts_at ascending, then past sessions by starts_at descending. No secondary ID order is specified for equal start times.
  • Refresh operates on all saved provider registrations for the authenticated user, not only the displayed category/page. Rows synced less than about five minutes ago are reused. Older rows are reconciled against provider subscriptions (up to 20 pages of 100); at most ten extra subscription-ID lookups recover entries omitted from provider lists. Cached statistics are retained when refresh fails. stale reports incomplete refresh and unavailable reports missing provider schema/configuration; these are not booking states or proof of live provider health.

Side effects

  • Default interest mode is read-only. Booked mode can refresh and update cached provider registrations/progress, even when no resulting session is displayed. It does not create or cancel subscriptions.

See it in Fieldmotion

CRM1

No direct CRM1 caller for Training_mySessions was found. The current catalogue/booking screen is CRM2 Training; tests are not production UI callers. No direct mobile-app or m-service caller for these CRM routes was found.

CRM2

Open Training → My Booked Webinars and filter for Training_mySessions with booked=1. The UI shows confirmed and pending rows, counts only confirmed bookings, and refreshes on returning focus from a provider tab.

Related endpoints