# Sessions

> Orchestrate multiple workflows into one KYC or onboarding case with sequential execution and shared data

Source: https://docs.korala.ai/guides/sessions

---

Sessions orchestrate multiple workflows into a single verification or onboarding case. Use sessions when you need to collect and verify multiple documents sequentially, attach related participants to the same case, or combine document workflows with review and provider-backed checks.

## Key Concepts

- **Session configurations**: Reusable blueprints that define which workflows, bindings, verification settings, and defaults a session uses.
- **Sequential execution**: Workflows run in order. The user must complete workflow 1 before starting workflow 2.
- **Participants**: Sessions can include a subject plus related parties such as beneficial owners, controllers, directors, or representatives.
- **Cross-workflow data flow**: Output from earlier workflows is available as input to later ones (e.g., validate POA name matches ID name).
- **Checks and risk**: Sessions can include provider-backed check workflows and native risk scoring before final resolution.
- **Resolution**: Sessions can be auto-resolved (approved/rejected) based on validation results, or manually resolved by a partner.
- **End-user access**: Each session gets a unique access token that your frontend can turn into the collection URL for end-users.

## Session Configurations

Before creating sessions, set up a configuration that defines the session blueprint. Configurations are org-scoped and reusable.

```typescript

const korala = new KoralaClient({
  apiKeyId: 'your-api-key-id',
  apiSecret: 'your-api-secret',
});

// Create a configuration
const config = await korala.sessions.createConfiguration({
  name: 'KYB Standard',
  slug: 'kyb-standard',
  description: 'Business onboarding with participant-aware verification',
  workflowBindings: [
    {
      workflowSlug: 'id-document',
      participantRoles: ['representative'],
      outputKey: 'representative_id',
    },
    {
      workflowSlug: 'proof-of-address',
      participantRoles: ['representative'],
      outputKey: 'representative_poa',
    },
    {
      workflowSlug: 'pep-check',
      participantRoles: ['beneficial_owner'],
      outputKey: 'ubo_pep_check',
    },
  ],
  subjectKind: 'business',
  isVerification: true,
  autoResolve: false,
  finalManualReviewRequired: true,
  defaultExpiresInMinutes: 1440,
  defaultRedirectUrl: 'https://yourapp.com/verification/complete',
});
```

### Configuration Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `name` | string | *required* | Display name |
| `slug` | string | *required* | URL-safe identifier (unique per org) |
| `workflowSlugs` | string[] | — | Ordered list of workflow slugs for simple sequential sessions |
| `workflowBindings` | object[] | — | Participant-aware workflow definitions with per-step context and output keys |
| `subjectKind` | `individual \\| business` | `individual` | Whether the case is for a person or business |
| `isVerification` | boolean | `true` | Enable resolution (approved/rejected) |
| `autoResolve` | boolean | `true` | Auto-resolve based on validation results |
| `finalManualReviewRequired` | boolean | `false` | Force partner review before final resolution |
| `defaultExpiresInMinutes` | number | `1440` | Default session expiration |
| `defaultRedirectUrl` | string | — | Default redirect after completion |

### Managing Configurations

```typescript
// List all configurations
const configs = await korala.sessions.listConfigurations();

// Get a specific configuration
const config = await korala.sessions.getConfiguration('kyc-standard');

// Update a configuration
await korala.sessions.updateConfiguration('kyc-standard', {
  defaultExpiresInMinutes: 2880,
});

// Delete a configuration
await korala.sessions.deleteConfiguration('kyc-standard');
```

## Creating a Session

Each session starts from a configuration:

```typescript
const session = await korala.sessions.create({
  externalUserId: 'org_abc123',
  configurationSlug: 'kyb-standard',
  participants: [
    { role: 'subject', displayName: 'Acme Corp' },
    { role: 'beneficial_owner', displayName: 'Jane Smith' },
    { role: 'representative', displayName: 'John Smith' },
  ],
  context: {
    partnerName: 'Acme Corp',
    applicationType: 'merchant_onboarding',
  },
  metadata: {
    applicationId: 'app_001',
  },
  // Override config defaults if needed
  expiresInMinutes: 720,
  redirectUrl: 'https://yourapp.com/custom-redirect',
});

// Share the access URL with the end-user
const accessUrl = `https://yourapp.korala.ai/v/${session.accessToken}`;
```

Use the session detail endpoint when you need full case state, including participants, workflow instances, checks, and risk summaries.

## Session Lifecycle

```
created → in_progress → completed (+ auto-resolve)
                      → pending_review → completed
                      → expired
                      → failed
```

| Status | Description |
|--------|-------------|
| `created` | Session created, user hasn't started yet |
| `in_progress` | User is completing workflows |
| `pending_review` | A workflow is paused for human review |
| `completed` | All workflows finished without failures |
| `expired` | Session expired before completion |
| `failed` | A workflow failed with no retries remaining |

## Resolution

When all workflows complete, the session may auto-resolve if enabled in the configuration and nothing requires manual review:

- **Approved**: All workflows passed validation
- **Rejected**: One or more workflows failed validation

For KYB or other review-heavy flows, the session can move into `pending_review` until a partner makes the final decision.

Partners can override the resolution at any time:

```typescript
await korala.sessions.resolve(sessionId, {
  resolution: 'approved',
  reason: 'Manually verified after review',
});
```

## Listing Sessions

```typescript
const sessions = await korala.sessions.list({
  externalUserId: 'usr_abc123',
  status: 'completed',
  page: 1,
  limit: 10,
});
```

## Session Webhooks

Subscribe to these events in your webhook configuration:

| Event | Description |
|-------|-------------|
| `session_completed` | All workflows in the session finished |
| `session_expired` | Session expired before completion |
| `session_failed` | Session failed (no retries remaining) |
| `session_resolved` | Resolution set (auto or manual) |
| `session_workflow_completed` | Individual workflow within session completed |
| `session_workflow_failed` | Individual workflow within session failed |

## Resubmission

If a workflow fails or the user must redo it, request resubmission:

```typescript
await korala.sessions.resubmit(sessionId, sessionWorkflowId);
```

This resets the workflow and all subsequent workflows, since the resubmission may invalidate their input data.

If downstream checks or risk summaries depended on the resubmitted workflow, Korala clears those results and recomputes them from the updated evidence.
