@datacline/langos-sdk-node 0.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,569 @@
1
+ type CandidateStatus = 'invited' | 'started' | 'completed' | 'cancelled' | 'error';
2
+ type SessionStatus = 'pending' | 'provisioning' | 'active' | 'submitted' | 'completed' | 'failed' | 'expired';
3
+ interface Assessment {
4
+ id: string;
5
+ object: 'assessment';
6
+ name: string;
7
+ description: string | null;
8
+ challengeCount: number;
9
+ createdAt: string;
10
+ updatedAt: string;
11
+ }
12
+ interface Candidate {
13
+ id: string;
14
+ object: 'candidate';
15
+ email: string;
16
+ name: string | null;
17
+ assessmentId: string;
18
+ externalId: string | null;
19
+ status: CandidateStatus;
20
+ invitationUrl: string | null;
21
+ invitedAt: string | null;
22
+ startedAt: string | null;
23
+ completedAt: string | null;
24
+ cancelledAt: string | null;
25
+ expiresAt: string | null;
26
+ latestSessionId: string | null;
27
+ score: number | null;
28
+ metadata: Record<string, unknown> | null;
29
+ createdAt: string;
30
+ updatedAt: string;
31
+ }
32
+ interface SessionSubmission {
33
+ language: string | null;
34
+ finalCode: string | null;
35
+ diff: string | null;
36
+ commitSha: string | null;
37
+ previewUrl: string | null;
38
+ }
39
+ interface SessionInsights {
40
+ aiUsagePercent: number | null;
41
+ testPassRate: number | null;
42
+ codeQuality: Record<string, unknown> | null;
43
+ [key: string]: unknown;
44
+ }
45
+ interface SessionFeedback {
46
+ notes: string | null;
47
+ problemSolvingScore: number | null;
48
+ codeQualityScore: number | null;
49
+ }
50
+ /**
51
+ * Typed activity counters surfaced from `session_analytics`. All counts are
52
+ * non-negative integers and default to `0` when no events have been recorded
53
+ * yet (`null` is never returned). Lets partner UIs render "candidate spent
54
+ * X minutes coding, ran tests Y times" without parsing the opaque `insights`
55
+ * JSON blob.
56
+ */
57
+ interface SessionAnalytics {
58
+ editorEventCount: number;
59
+ runEventCount: number;
60
+ testEventCount: number;
61
+ aiEventCount: number;
62
+ pasteEventCount: number;
63
+ activeSeconds: number;
64
+ idleSeconds: number;
65
+ codingSeconds: number;
66
+ }
67
+ interface Session {
68
+ id: string;
69
+ object: 'session';
70
+ candidateId: string;
71
+ assessmentId: string;
72
+ status: SessionStatus;
73
+ attempt: number;
74
+ startedAt: string | null;
75
+ completedAt: string | null;
76
+ durationSeconds: number | null;
77
+ score: number | null;
78
+ passed: boolean | null;
79
+ /**
80
+ * Partner-readable HTML report URL. Click-through opens a server-rendered
81
+ * report page for the recruiter (no Langos login required). `null` when the
82
+ * session has no calculated score yet.
83
+ */
84
+ reportUrl: string | null;
85
+ submission: SessionSubmission | null;
86
+ /** Typed activity stats; companion to the opaque `insights` blob. */
87
+ analytics: SessionAnalytics;
88
+ insights: SessionInsights | null;
89
+ feedback: SessionFeedback | null;
90
+ createdAt: string;
91
+ updatedAt: string;
92
+ }
93
+ /**
94
+ * Canonical Langos plan tiers. Mirrors the public pricing page at
95
+ * https://www.langos.io/#pricing — the source of truth lives in the server's
96
+ * `plan-features.json`. No aliases, no synonyms; if a partner sees an unknown
97
+ * value here it's a deploy mismatch, not a plan tier we forgot to add.
98
+ *
99
+ * Note: `mid_tier` is the canonical key. There is no `mid` shorthand.
100
+ */
101
+ type PlanTier = 'free' | 'starter' | 'mid_tier' | 'growth' | 'custom';
102
+ /**
103
+ * Account info for the Langos company that owns the calling integration.
104
+ * Returned by `client.account.retrieve()`.
105
+ */
106
+ interface Account {
107
+ id: string;
108
+ object: 'account';
109
+ name: string;
110
+ /**
111
+ * Immutable, auto-assigned URL slug for this company. Stable across the
112
+ * company's lifetime; safe to embed in your UI/links. Server-generated on
113
+ * signup — partners cannot set it.
114
+ */
115
+ slug: string;
116
+ /**
117
+ * The company's current plan tier. One of `free | starter | mid_tier |
118
+ * growth | custom`. Use this to gate UI on `planCaps` rather than hardcoding
119
+ * tier strings.
120
+ */
121
+ planTier: PlanTier;
122
+ billingCycle: string;
123
+ status: string;
124
+ sessionsUsed: number;
125
+ /** `null` on unlimited plans (e.g. `custom`). */
126
+ sessionsLimit: number | null;
127
+ /** `null` on unlimited plans (e.g. `custom`). */
128
+ sessionsRemaining: number | null;
129
+ trialEndsAt: string | null;
130
+ /**
131
+ * Top-level feature flags derived from the plan-features matrix and runtime
132
+ * configuration. Each flag answers "can this account use feature X right now?"
133
+ *
134
+ * - `webIdeEnabled` — true when the plan includes the web IDE.
135
+ * - `replayEnabled` — true when the plan includes session replay.
136
+ * - `aiAssistanceEnabled` — true ONLY when the plan includes AI assistance
137
+ * AND an Anthropic API key is configured for the company. (Tier alone
138
+ * isn't enough; AI is gated by tier but inert without a key.)
139
+ */
140
+ features: AccountFeatures;
141
+ /**
142
+ * What the company's plan tier *includes*, mirrored from the public pricing
143
+ * page. Read-only — partners use this to render upgrade prompts (e.g. "your
144
+ * plan caps at 30 sessions/mo, upgrade for unlimited"). `null` when the
145
+ * company is on a legacy or unknown tier.
146
+ */
147
+ planCaps: PlanCaps | null;
148
+ integration: AccountIntegration;
149
+ }
150
+ /**
151
+ * Plan capability block, mirrored from `plan-features.json` on the server.
152
+ * The shape mirrors the public pricing page: render upgrade prompts from this
153
+ * rather than hardcoding plan limits in your UI.
154
+ */
155
+ interface PlanCaps {
156
+ label: string;
157
+ priceMonthly: number | null;
158
+ /** Billing cadence. Currently always `'monthly'`. */
159
+ billing: 'monthly';
160
+ /** Display currency. Currently always `'USD'`. */
161
+ currency: 'USD';
162
+ /** Sessions per billing period. `null` on unlimited tiers. */
163
+ sessionLimit: number | null;
164
+ /** Library challenges available out of the box. `null` on unlimited tiers. */
165
+ readyMadeChallenges: number | null;
166
+ /** Max custom challenges the company can author. `null` on unlimited tiers. */
167
+ customChallengesMax: number | null;
168
+ /**
169
+ * Raw feature matrix from plan-features.json — keys like `web_ide`,
170
+ * `replay`, `ai_assistance`, `sso`, etc. Prefer the typed `Account.features`
171
+ * for the small set of flags surfaced at top level.
172
+ */
173
+ features: Record<string, boolean>;
174
+ support: string;
175
+ popular: boolean;
176
+ contactSales: boolean;
177
+ }
178
+ /**
179
+ * Top-level feature flags, derived from `plan_caps.features` plus runtime
180
+ * configuration (see `aiAssistanceEnabled`).
181
+ */
182
+ interface AccountFeatures {
183
+ /** True when `plan_caps.features.web_ide` is true. */
184
+ webIdeEnabled: boolean;
185
+ /** True when `plan_caps.features.replay` is true. */
186
+ replayEnabled: boolean;
187
+ /**
188
+ * True only when `plan_caps.features.ai_assistance` is true AND an
189
+ * Anthropic API key is configured for the company. Without the key, AI is
190
+ * gated by tier but would be inert at runtime.
191
+ */
192
+ aiAssistanceEnabled: boolean;
193
+ }
194
+ interface AccountIntegration {
195
+ /**
196
+ * Which integration path issued the calling API key.
197
+ *
198
+ * - `"customer"` — this key was minted from the Langos dashboard and used
199
+ * directly via this SDK.
200
+ * - `"ashby"` (or another ATS slug) — Langos was wired through your ATS
201
+ * partner; the customer is operating Langos inside the partner's UI.
202
+ *
203
+ * Both paths surface the same `/v1/account` data and call the same API.
204
+ */
205
+ provider: string;
206
+ apiKeyPrefix: string;
207
+ scopes: string[];
208
+ rateLimitPerMinute: number | null;
209
+ webhookUrl: string | null;
210
+ }
211
+ interface WebhookEndpoint {
212
+ object: 'webhook_endpoint';
213
+ webhookUrl: string | null;
214
+ /**
215
+ * The `whsec_…` signing secret. Only returned once, immediately after a
216
+ * `rotateSigningSecret: true` call. Subsequent reads return `null`.
217
+ */
218
+ signingSecret: string | null;
219
+ }
220
+ interface WebhookEndpointParams {
221
+ /** Absolute http(s) URL, or `null` to disable outbound delivery. */
222
+ webhookUrl?: string | null;
223
+ /**
224
+ * Generate a fresh signing secret. The previous secret is overwritten
225
+ * and cannot be recovered — store the response value.
226
+ */
227
+ rotateSigningSecret?: boolean;
228
+ }
229
+ interface CandidateCreateParams {
230
+ email: string;
231
+ assessmentId: string;
232
+ name?: string;
233
+ externalId?: string;
234
+ expiresAt?: string | Date;
235
+ metadata?: Record<string, unknown>;
236
+ }
237
+ interface ListParams {
238
+ limit?: number;
239
+ cursor?: string;
240
+ }
241
+ interface CandidateListParams extends ListParams {
242
+ status?: CandidateStatus;
243
+ assessmentId?: string;
244
+ }
245
+ interface AssessmentListParams extends ListParams {
246
+ }
247
+ interface SessionListParams extends ListParams {
248
+ }
249
+ /**
250
+ * Per-call request options. Override SDK defaults (timeout, retries) for a
251
+ * single call, supply an `AbortSignal`, or attach extra headers.
252
+ */
253
+ interface RequestOptions {
254
+ timeout?: number;
255
+ maxRetries?: number;
256
+ signal?: AbortSignal;
257
+ headers?: Record<string, string>;
258
+ idempotencyKey?: string;
259
+ }
260
+ interface Logger {
261
+ debug(obj: object, msg?: string): void;
262
+ info(obj: object, msg?: string): void;
263
+ warn(obj: object, msg?: string): void;
264
+ error(obj: object, msg?: string): void;
265
+ }
266
+ interface LangosOptions {
267
+ apiKey: string;
268
+ baseUrl?: string;
269
+ timeout?: number;
270
+ maxRetries?: number;
271
+ fetch?: typeof fetch;
272
+ logger?: Logger;
273
+ /** Free-form identifier appended to the User-Agent (e.g. "GreenhouseConnector/2.1.0"). */
274
+ appName?: string;
275
+ /** Disables outbound client telemetry header. */
276
+ telemetry?: boolean;
277
+ }
278
+ interface PageMeta {
279
+ hasMore: boolean;
280
+ nextCursor: string | null;
281
+ }
282
+ interface Page<T> extends PageMeta {
283
+ data: T[];
284
+ /** Fetches the next page. Returns null when `hasMore` is false. */
285
+ getNextPage: () => Promise<Page<T> | null>;
286
+ }
287
+ type AsyncIterablePage<T> = AsyncIterable<T> & Page<T>;
288
+ type WebhookEventType = 'session.submitted' | 'session.completed' | 'candidate.cancelled';
289
+ /**
290
+ * Discriminated union of webhook event payloads. Each `type` narrows `data` to
291
+ * the corresponding shape so partners can `switch (event.type)` and let the
292
+ * compiler enforce exhaustive handling. When the server adds new event types,
293
+ * surface them here in lockstep.
294
+ */
295
+ type Event = SessionSubmittedEvent | SessionCompletedEvent | CandidateCancelledEvent;
296
+ interface BaseEvent<TType extends WebhookEventType, TData> {
297
+ id: string;
298
+ object: 'event';
299
+ type: TType;
300
+ created: string;
301
+ data: TData;
302
+ }
303
+ type SessionSubmittedEvent = BaseEvent<'session.submitted', Session>;
304
+ type SessionCompletedEvent = BaseEvent<'session.completed', Session>;
305
+ type CandidateCancelledEvent = BaseEvent<'candidate.cancelled', Candidate>;
306
+ interface WebhookEvent<T = unknown> {
307
+ id: string;
308
+ object: 'event';
309
+ type: WebhookEventType;
310
+ created: string;
311
+ data: T;
312
+ }
313
+
314
+ interface ResolvedClientConfig {
315
+ apiKey: string;
316
+ baseUrl: string;
317
+ timeout: number;
318
+ maxRetries: number;
319
+ fetchImpl: typeof fetch;
320
+ logger: Logger;
321
+ appName: string | undefined;
322
+ telemetry: boolean;
323
+ }
324
+
325
+ declare class APIResource {
326
+ protected readonly cfg: ResolvedClientConfig;
327
+ constructor(cfg: ResolvedClientConfig);
328
+ protected get<T>(path: string, query?: Record<string, string | number | undefined | null>, options?: RequestOptions): Promise<T>;
329
+ protected post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
330
+ protected delete<T>(path: string, options?: RequestOptions): Promise<T>;
331
+ protected patch<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
332
+ }
333
+
334
+ /**
335
+ * `client.account` — read the company info that owns this integration, and
336
+ * manage the outbound webhook endpoint.
337
+ *
338
+ * Typical usage:
339
+ *
340
+ * ```ts
341
+ * const account = await client.account.retrieve();
342
+ * if (account.sessionsRemaining === 0) {
343
+ * showUpgradePrompt();
344
+ * }
345
+ *
346
+ * await client.account.setWebhookEndpoint({
347
+ * webhookUrl: 'https://greenhouse.example.com/webhooks/langos',
348
+ * rotateSigningSecret: true,
349
+ * });
350
+ * ```
351
+ */
352
+ declare class AccountResource extends APIResource {
353
+ /**
354
+ * Read the calling integration's account.
355
+ *
356
+ * Includes plan, quota, feature flags, and integration metadata
357
+ * (key prefix, scopes, rate limit, webhook URL).
358
+ *
359
+ * @returns {Promise<Account>}
360
+ */
361
+ retrieve(options?: RequestOptions): Promise<Account>;
362
+ /**
363
+ * Set or clear the outbound webhook URL, and optionally rotate the signing
364
+ * secret.
365
+ *
366
+ * When `rotateSigningSecret: true`, the response includes the new secret in
367
+ * `signingSecret`. Store it — the secret cannot be re-fetched. Subsequent
368
+ * reads return `signingSecret: null`.
369
+ *
370
+ * @param {WebhookEndpointParams} params
371
+ */
372
+ setWebhookEndpoint(params: WebhookEndpointParams, options?: RequestOptions): Promise<WebhookEndpoint>;
373
+ }
374
+
375
+ declare class AssessmentsResource extends APIResource {
376
+ list(params?: AssessmentListParams, options?: RequestOptions): Promise<AsyncIterablePage<Assessment>>;
377
+ retrieve(id: string, options?: RequestOptions): Promise<Assessment>;
378
+ }
379
+
380
+ declare class CandidatesResource extends APIResource {
381
+ list(params?: CandidateListParams, options?: RequestOptions): Promise<AsyncIterablePage<Candidate>>;
382
+ retrieve(id: string, options?: RequestOptions): Promise<Candidate>;
383
+ create(params: CandidateCreateParams, options?: RequestOptions): Promise<Candidate>;
384
+ /** Idempotent — calling twice on a cancelled candidate returns the same record. */
385
+ cancel(id: string, options?: RequestOptions): Promise<Candidate>;
386
+ }
387
+
388
+ declare class SessionsResource extends APIResource {
389
+ retrieve(id: string, options?: RequestOptions): Promise<Session>;
390
+ listForCandidate(candidateId: string, params?: SessionListParams, options?: RequestOptions): Promise<AsyncIterablePage<Session>>;
391
+ }
392
+
393
+ declare class Langos {
394
+ readonly account: AccountResource;
395
+ readonly assessments: AssessmentsResource;
396
+ readonly candidates: CandidatesResource;
397
+ readonly sessions: SessionsResource;
398
+ /**
399
+ * Webhook signature helpers (`Langos.webhooks.constructEvent`). Static-style:
400
+ * does not need the client instance, since signing is independent of API
401
+ * calls. Exposed both as a class member and as `Langos.webhooks` for parity
402
+ * with Stripe's `stripe.webhooks` style.
403
+ */
404
+ readonly webhooks: {
405
+ constructEvent<T = unknown>(payload: string | Buffer, signatureHeader: string | string[] | undefined | null, secret: string, tolerance?: number): WebhookEvent<T>;
406
+ };
407
+ static readonly webhooks: {
408
+ constructEvent<T = unknown>(payload: string | Buffer, signatureHeader: string | string[] | undefined | null, secret: string, tolerance?: number): WebhookEvent<T>;
409
+ };
410
+ private readonly cfg;
411
+ constructor(options: LangosOptions);
412
+ }
413
+
414
+ /**
415
+ * Structured details merged into the 402 `quota_exceeded` error body. The
416
+ * server emits these as top-level fields alongside the standard problem+json
417
+ * envelope; partners can render an upgrade prompt without parsing free-form
418
+ * text.
419
+ */
420
+ interface QuotaExceededDetails {
421
+ sessions_used: number;
422
+ sessions_limit: number;
423
+ /** ISO timestamp when the quota window resets. */
424
+ reset_at: string;
425
+ /** Absolute URL to the upgrade page; `null` if the server can't build one. */
426
+ upgrade_url: string | null;
427
+ /** The plan tier that hit the cap (e.g. `mid_tier`, `growth`). */
428
+ plan_tier: string;
429
+ }
430
+ /**
431
+ * Structured details merged into the 403 `feature_not_available` error body.
432
+ * Returned when an integration calls a feature its plan tier does not include
433
+ * (e.g. asking for replay on `starter`).
434
+ */
435
+ interface FeatureNotAvailableDetails {
436
+ /** The plan-features key that is gated off (e.g. `replay`, `ai_assistance`). */
437
+ feature: string;
438
+ /** Absolute URL to the upgrade page; `null` if the server can't build one. */
439
+ upgrade_url: string | null;
440
+ }
441
+ interface LangosErrorBody {
442
+ type?: string;
443
+ title?: string;
444
+ status?: number;
445
+ detail?: string;
446
+ code?: string;
447
+ request_id?: string;
448
+ errors?: Array<{
449
+ field: string;
450
+ message: string;
451
+ code?: string;
452
+ }>;
453
+ [extra: string]: unknown;
454
+ }
455
+ declare class LangosError extends Error {
456
+ constructor(message: string);
457
+ }
458
+ /** Thrown when an HTTP response is received and indicates an error (>= 400). */
459
+ declare class LangosAPIError extends LangosError {
460
+ readonly status: number;
461
+ readonly code: string | undefined;
462
+ readonly requestId: string | undefined;
463
+ readonly headers: Headers;
464
+ readonly body: LangosErrorBody | undefined;
465
+ readonly errors: LangosErrorBody['errors'] | undefined;
466
+ constructor(status: number, body: LangosErrorBody | undefined, headers: Headers, fallbackMessage: string);
467
+ /**
468
+ * Typed accessor for 402 `quota_exceeded` errors. Returns the structured
469
+ * details payload (sessions used/limit, reset timestamp, upgrade URL, plan
470
+ * tier) when the error matches; otherwise `null`.
471
+ *
472
+ * Use this instead of reaching into `err.body` to render upgrade prompts.
473
+ */
474
+ get quotaDetails(): QuotaExceededDetails | null;
475
+ /**
476
+ * Typed accessor for 403 `feature_not_available` errors. Returns the gated
477
+ * feature key and an upgrade URL; otherwise `null`.
478
+ */
479
+ get featureDetails(): FeatureNotAvailableDetails | null;
480
+ static from(status: number, body: unknown, headers: Headers): LangosAPIError;
481
+ }
482
+ declare const LangosAuthenticationError: {
483
+ new (...args: any[]): {
484
+ name: string;
485
+ message: string;
486
+ stack?: string;
487
+ cause?: unknown;
488
+ };
489
+ } & typeof LangosAPIError;
490
+ type LangosAuthenticationError = LangosAPIError;
491
+ declare const LangosForbiddenError: {
492
+ new (...args: any[]): {
493
+ name: string;
494
+ message: string;
495
+ stack?: string;
496
+ cause?: unknown;
497
+ };
498
+ } & typeof LangosAPIError;
499
+ type LangosForbiddenError = LangosAPIError;
500
+ declare const LangosNotFoundError: {
501
+ new (...args: any[]): {
502
+ name: string;
503
+ message: string;
504
+ stack?: string;
505
+ cause?: unknown;
506
+ };
507
+ } & typeof LangosAPIError;
508
+ type LangosNotFoundError = LangosAPIError;
509
+ declare const LangosBadRequestError: {
510
+ new (...args: any[]): {
511
+ name: string;
512
+ message: string;
513
+ stack?: string;
514
+ cause?: unknown;
515
+ };
516
+ } & typeof LangosAPIError;
517
+ type LangosBadRequestError = LangosAPIError;
518
+ declare const LangosConflictError: {
519
+ new (...args: any[]): {
520
+ name: string;
521
+ message: string;
522
+ stack?: string;
523
+ cause?: unknown;
524
+ };
525
+ } & typeof LangosAPIError;
526
+ type LangosConflictError = LangosAPIError;
527
+ declare const LangosServerError: {
528
+ new (...args: any[]): {
529
+ name: string;
530
+ message: string;
531
+ stack?: string;
532
+ cause?: unknown;
533
+ };
534
+ } & typeof LangosAPIError;
535
+ type LangosServerError = LangosAPIError;
536
+ declare class LangosRateLimitError extends LangosAPIError {
537
+ readonly retryAfter: number | undefined;
538
+ constructor(status: number, body: LangosErrorBody | undefined, headers: Headers, fallback: string, retryAfter: number | undefined);
539
+ }
540
+ /** Thrown when the underlying fetch fails (DNS, TCP, TLS). */
541
+ declare class LangosConnectionError extends LangosError {
542
+ readonly cause: unknown;
543
+ constructor(message: string, cause: unknown);
544
+ }
545
+ /** Thrown when a request exceeds the configured timeout. */
546
+ declare class LangosTimeoutError extends LangosError {
547
+ readonly timeoutMs: number;
548
+ constructor(timeoutMs: number);
549
+ }
550
+ /** Thrown by `Langos.webhooks.constructEvent` when signature verification fails. */
551
+ declare class LangosSignatureVerificationError extends LangosError {
552
+ constructor(reason: string);
553
+ }
554
+
555
+ /**
556
+ * Webhook helpers. v1.0 ships verification only — outbound delivery from Langos
557
+ * is on the roadmap. Partners can wire `constructEvent` against the planned
558
+ * signature header today; the SDK contract will not change when delivery lands.
559
+ *
560
+ * Pattern matches Stripe's `stripe.webhooks.constructEvent` so partners with
561
+ * existing handlers re-use the same shape.
562
+ */
563
+ declare const Webhooks: {
564
+ constructEvent<T = unknown>(payload: string | Buffer, signatureHeader: string | string[] | undefined | null, secret: string, tolerance?: number): WebhookEvent<T>;
565
+ };
566
+
567
+ declare const version = "0.2.0-alpha.1";
568
+
569
+ export { type Account, type AccountFeatures, type AccountIntegration, type Assessment, type AssessmentListParams, type AsyncIterablePage, type Candidate, type CandidateCancelledEvent, type CandidateCreateParams, type CandidateListParams, type CandidateStatus, type Event, type FeatureNotAvailableDetails, Langos, LangosAPIError, LangosAuthenticationError, LangosBadRequestError, LangosConflictError, LangosConnectionError, LangosError, type LangosErrorBody, LangosForbiddenError, LangosNotFoundError, type LangosOptions, LangosRateLimitError, LangosServerError, LangosSignatureVerificationError, LangosTimeoutError, type Logger, type Page, type PageMeta, type PlanCaps, type PlanTier, type QuotaExceededDetails, type RequestOptions, type Session, type SessionAnalytics, type SessionCompletedEvent, type SessionFeedback, type SessionInsights, type SessionListParams, type SessionStatus, type SessionSubmission, type SessionSubmittedEvent, type WebhookEndpoint, type WebhookEndpointParams, type WebhookEvent, type WebhookEventType, Webhooks, version };