Documentation Index
Fetch the complete documentation index at: https://docs.talview.com/llms.txt
Use this file to discover all available pages before exploring further.
What is Scheduler module
The Scheduler module is part of the Proview SDK, exposed as Proview.scheduler. It provides a candidate-facing interface for managing interview scheduler workflows with integrated authentication.
Once initialized, it lets your application:
- Fetch meetings — retrieve a candidate’s scheduled interviews and their current state.
- Respond to interviews — accept, decline, propose a new time, or submit availability on behalf of the candidate.
- Render scheduler UI — mount a prebuilt scheduler interface in
inline, sidebar, or modal layout.
- React to state changes — subscribe to events for phase transitions, route changes, and errors.
Both Promise-based and callback-based async patterns are supported. All UI text is localizable via the locale option.
Quickstart
All async methods support both Promises and an optional callback. This walkthrough uses Promises. See Callback Signature for the callback form.
1. Initialize credential
The SDK supports Firebase as a credentialing provider for authentication.
const firebaseCredential = Proview.auth.FirebaseAuthStrategy({
token: 'your-firebase-auth-token',
});
2. Initialize scheduler
Call Proview.scheduler.init() with the Firebase credential. The SDK authenticates the user and makes the user object available globally at Proview.user.
const scheduler = Proview.scheduler.init({
dsn: 'project-dsn',
projectId: 'project-123',
credential: firebaseCredential,
});
// Access user object globally
const user = Proview.user;
console.log(user.uid, user.email, user.displayName);
// Get ID token when needed
const idToken = await user.getIdToken();
3. Fetch meetings
const meetings = await scheduler.fetchMeetings();
// => MeetingSummary[]
4. Fetch state for a specific meeting
const state = await scheduler.fetchMeeting('meeting_123');
// => SchedulerState | null
5. Respond to an interview
Accept:
const updated = await scheduler.acceptMeeting({
meetingId: 'meeting_123',
interviewId: 'interview_456',
reason: 'Confirmed',
});
Decline:
const updated = await scheduler.declineMeeting({
meetingId: 'meeting_123',
interviewId: 'interview_456',
reason: 'Not available',
});
Propose a new time (when the candidate wants to reschedule):
const updated = await scheduler.proposeNewTime({
meetingId: 'meeting_123',
interviewId: 'interview_456',
slotId: 'slot_789',
note: 'Prefer morning slots',
});
Set availability (saves the candidate’s general availability; not scoped to a single meeting):
const updated = await scheduler.setAvailability({
meetingId: 'meeting_123',
weekly: {
monday: [{ start: '09:00', end: '17:00' }],
wednesday: [{ start: '10:00', end: '15:00' }],
},
blockedDates: ['2026-04-01'],
});
6. Render the scheduler UI
Mount the scheduler UI into any container element. Three layout modes are supported: inline, sidebar, and modal.
const mounted = scheduler.mount({
initialView: 'scheduled_interviews',
mountMode: {
mode: 'inline',
containerId: 'proview-scheduler-root',
},
});
7. Navigate programmatically
Use scheduler.navigate() to trigger a view change from outside the UI:
scheduler.navigate('interviews', { meetingId: 'meeting_123' });
Use mounted.setView() to change the view from the mounted instance directly:
mounted.setView('scheduled_interviews', { meetingId: 'meeting_123' });
8. Listen to events
on() returns an unsubscribe function, useful for cleanup in component lifecycles:
const unsubscribe = scheduler.on('state.changed', ({ previous, current }) => {
console.log('Phase changed:', previous.phase, '->', current.phase);
});
// Later, to stop listening:
unsubscribe();
9. Teardown
When done, unmount the UI and destroy the session:
mounted.unmount();
scheduler.destroy();
API Reference
Creates a scheduler session.
Input
type SchedulerInitInput = {
dsn: string; // Required: Project DSN
projectId: string; // Required: Project ID
credential: Credential; // Required: Authentication credential (e.g., FirebaseAuthStrategy)
};
Returns — SchedulerSession
type SchedulerSession = {
fetchMeeting(meetingId: string, cb?: MeetingStateCallback): Promise<SchedulerState | null>;
fetchMeetings(cb?: MeetingsCallback): Promise<MeetingSummary[]>;
acceptMeeting(payload: AcceptMeetingInput, cb?: MeetingStateCallback): Promise<SchedulerState>;
declineMeeting(payload: DeclineMeetingInput, cb?: MeetingStateCallback): Promise<SchedulerState>;
proposeNewTime(payload: ProposeNewTimeInput, cb?: MeetingStateCallback): Promise<SchedulerState>;
setAvailability(payload: SetAvailabilityInput, cb?: MeetingStateCallback): Promise<SchedulerState>;
mount(options: MountOptions): MountedSchedulerUi;
navigate(view: SchedulerView, options: { meetingId: string }): void;
getCurrentView(): SchedulerView;
on<E extends SchedulerEventName>(event: E, handler: (payload: SchedulerEventPayloadMap[E]) => void): () => void;
off<E extends SchedulerEventName>(event: E, handler: (payload: SchedulerEventPayloadMap[E]) => void): void;
destroy(): void;
};
The authenticated user is available globally at Proview.user after initialization.
User Object
After initializing the scheduler module, Proview.user provides a Firebase-compatible user object accessible globally.
User Interface
type User = {
uid: string; // User's unique ID
email: string | null; // User's email address
displayName: string | null; // User's display name
emailVerified: boolean; // Email verification status
isAnonymous?: boolean; // Is anonymous user
metadata?: UserMetadata; // Creation and last sign-in time
providerData?: ProviderData[]; // Provider-specific info
// Methods
getIdToken(forceRefresh?: boolean): Promise<string>;
getIdTokenResult(forceRefresh?: boolean): Promise<IdTokenResult>;
};
Example:
const firebaseCredential = Proview.auth.FirebaseAuthStrategy({
apiKey: 'your-firebase-api-key',
authDomain: 'your-project.firebaseapp.com',
projectId: 'your-firebase-project-id',
});
const scheduler = Proview.scheduler.init({
dsn: 'project-dsn',
projectId: 'project-123',
credential: firebaseCredential,
});
// Access user properties globally
const user = Proview.user;
console.log(user.uid);
console.log(user.email);
console.log(user.displayName);
console.log(user.emailVerified);
// Get ID token
const idToken = await user.getIdToken();
// Force refresh token
const freshToken = await user.getIdToken(true);
Firebase Authentication
Proview.auth.FirebaseAuthStrategy(config)
Creates a Firebase authentication credential for use with the Proview SDK modules.
Input
type FirebaseAuthStrategyConfig = {
token: string; // Required: Firebase authentication token
};
Returns — FirebaseAuthStrategy
A credential object that can be passed to any Proview SDK module initialization.
Example:
// Initialize Firebase credential with token
const firebaseCredential = Proview.auth.FirebaseAuthStrategy({
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
});
// Use with scheduler module
const scheduler = Proview.scheduler.init({
dsn: 'project-dsn',
projectId: 'project-123',
credential: firebaseCredential,
});
fetchMeetings(cb?)
Returns all meetings for the candidate.
| |
|---|
| Input | None |
| Promise | Promise<MeetingSummary[]> |
| Callback | (error: SchedulerError | null, meetings?: MeetingSummary[]) => void |
fetchMeeting(meetingId, cb?)
Returns the current scheduler state for one meeting.
| |
|---|
| Input | meetingId: string |
| Promise | Promise<SchedulerState | null> |
| Callback | (error: SchedulerError | null, state?: SchedulerState | null) => void |
acceptMeeting(payload, cb?)
Accepts a specific interview within a meeting.
Input
type AcceptMeetingInput = {
meetingId: string;
interviewId: string;
reason?: string;
};
| |
|---|
| Promise | Promise<SchedulerState> |
| Callback | (error: SchedulerError | null, state?: SchedulerState | null) => void |
declineMeeting(payload, cb?)
Declines a specific interview within a meeting.
Input
type DeclineMeetingInput = {
meetingId: string;
interviewId: string;
reason?: string;
};
| |
|---|
| Promise | Promise<SchedulerState> |
| Callback | (error: SchedulerError | null, state?: SchedulerState | null) => void |
proposeNewTime(payload, cb?)
Submits a candidate’s preferred alternative time slot.
Input
type ProposeNewTimeInput = {
meetingId: string;
interviewId: string;
slotId: string; // ID of the available slot to propose
note?: string;
};
| |
|---|
| Promise | Promise<SchedulerState> |
| Callback | (error: SchedulerError | null, state?: SchedulerState | null) => void |
setAvailability(payload, cb?)
Saves the candidate’s general availability for scheduler. Availability is candidate-scoped, not tied to a specific meeting. The meetingId provides session context for the operation.
Input
type SetAvailabilityInput = {
meetingId: string;
// Recurring weekly time windows. start/end use HH:MM (24-hour) format.
weekly: Partial<
Record<
'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday',
Array<{ start: string; end: string }>
>
>;
blockedDates: string[]; // Specific dates to exclude, in YYYY-MM-DD format
};
| |
|---|
| Promise | Promise<SchedulerState> |
| Callback | (error: SchedulerError | null, state?: SchedulerState | null) => void |
mount(options)
Mounts the scheduler UI into a host element.
Input
type SchedulerView = 'scheduled_interviews' | 'interviews';
type MountOptions = {
// View to show on first render. Defaults to 'scheduled_interviews'.
initialView?: SchedulerView;
// BCP 47 locale tag (e.g. 'en-US', 'fr-FR'). Defaults to the browser locale.
locale?: string;
// 'sdk' — the SDK renders its own error UI.
// 'host' — errors are surfaced via the 'session.error' event for the host app to handle.
errorMode?: 'sdk' | 'host';
mountMode:
| { mode: 'inline'; containerId: string }
| { mode: 'sidebar'; containerId: string; width?: number }
| { mode: 'modal'; containerId: string; closeOnBackdrop?: boolean; title?: string };
views?: {
interviews?: {
// Which tab to show first in the interviews view.
initialTab?: 'upcoming' | 'completed';
};
};
};
Returns — MountedSchedulerUi
type MountedSchedulerUi = {
unmount(): void;
setView(
view: SchedulerView,
options: {
meetingId: string;
// Arbitrary key-value data passed through to 'ui.route.changed' events.
metadata?: Record<string, string | number | boolean | null>;
},
): void;
};
navigate(view, options)
Navigates the mounted UI to a target view. Equivalent to mounted.setView() but called on the session rather than the mounted instance.
| |
|---|
view | SchedulerView |
options | { meetingId: string } |
| Returns | void |
getCurrentView()
Returns the currently active view name.
on(event, handler) / off(event, handler)
Subscribes or unsubscribes from scheduler events. on() returns an unsubscribe function as a convenience alternative to calling off().
Event names and payloads
| Event | Payload |
|---|
state.changed | { previous: SchedulerState; current: SchedulerState; source: 'command' | 'remote' } |
ui.route.changed | { from: SchedulerView | null; to: SchedulerView; mode: 'memory' | 'host_v8'; meetingId?: string } |
ui.rendered | { view: SchedulerView; mode: UiMode; containerId?: string } |
session.error | SchedulerError |
session.destroyed | { meetingId: string; participantId: string; destroyedAt: string } |
Full type definitions
type SchedulerPhase =
| 'loading'
| 'invited'
| 'confirmed'
| 'declined'
| 'proposed'
| 'proposal_declined'
| 'cancelled'
| 'completed'
| 'expired';
type UiMode = 'inline' | 'sidebar' | 'modal';
type SchedulerError = {
code: string;
message: string;
recoverable: boolean;
source: 'network' | 'auth' | 'validation' | 'internal';
};
type MeetingSummary = {
meetingId: string;
phase: SchedulerPhase;
startAt: string; // ISO 8601
endAt: string; // ISO 8601
title: string;
round: string;
mode: string;
};
type SchedulerState = {
meetingId: string;
participantId: string;
phase: SchedulerPhase;
interviews: Array<{
interviewId: string;
title: string;
round: string;
type: string;
mode: string;
jobId: string;
startAt: string; // ISO 8601
endAt: string; // ISO 8601
rsvpStatus: 'pending' | 'confirmed' | 'declined' | 'proposed';
join: { enabled: boolean; url?: string };
}>;
availability: {
weekly: Record<string, Array<{ start: string; end: string }>>;
blockedDates: string[]; // YYYY-MM-DD
};
view: SchedulerView;
tabs: {
active: 'upcoming' | 'completed';
};
lastSyncedAt?: string; // ISO 8601
};
type SchedulerEventName =
| 'state.changed'
| 'ui.route.changed'
| 'ui.rendered'
| 'session.error'
| 'session.destroyed';
type SchedulerEventPayloadMap = {
'state.changed': {
previous: SchedulerState;
current: SchedulerState;
source: 'command' | 'remote';
};
'ui.route.changed': {
from: SchedulerView | null;
to: SchedulerView;
mode: 'memory' | 'host_v8';
meetingId?: string;
};
'ui.rendered': {
view: SchedulerView;
mode: UiMode;
containerId?: string;
};
'session.error': SchedulerError;
'session.destroyed': {
meetingId: string;
participantId: string;
destroyedAt: string;
};
};
destroy()
Cleans up the scheduler session and all event listeners. Call mounted.unmount() first if the UI is still mounted.
Callback Signature
All async methods accept an optional callback as the last argument. The callback uses a Node.js-style error-first signature.
type MeetingStateCallback = (error: SchedulerError | null, state?: SchedulerState | null) => void;
type MeetingsCallback = (error: SchedulerError | null, meetings?: MeetingSummary[]) => void;
Either style works:
// Promise
const state = await scheduler.acceptMeeting(payload);
// Callback
scheduler.acceptMeeting(payload, (error, state) => {
if (error) return;
// handle updated state
});