> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corti.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API Reference

> Complete reference for all API methods across all integration approaches

This page provides a complete reference for all API methods available in the Corti Embedded Assistant.

<Info>
  **Applies to all integration methods**

  This API Reference documents operations available across all three integration approaches:

  * [**Web Component API**](/assistant/web-component-api) (recommended) - `cortiEmbeddedElement.methodName()`
  * [**Window API**](/assistant/window-api) - `window.CortiEmbedded.v1.methodName()`
  * [**PostMessage API**](/assistant/postmessage-api) - `postMessage({ action: 'methodName', payload: {...} })`

  The underlying capabilities and error model are shared, but the public invocation shape differs by integration method. Examples on this page use the package-facing Web Component / React API unless noted otherwise.
</Info>

<Check>
  **Examples use Web Component API**

  All code examples on this page use the Web Component API pattern for clarity and consistency. This is the recommended integration method for most use cases.
</Check>

## Using the API

### In React components

Use the `useCortiEmbeddedApi` hook to access API methods:

```tsx theme={null}
import { useRef } from "react";
import {
  CortiEmbeddedReact,
  useCortiEmbeddedApi,
  type CortiEmbeddedReactRef,
} from "@corti/embedded-web/react";

function MyComponent() {
  const cortiRef = useRef<CortiEmbeddedReactRef>(null);
  const api = useCortiEmbeddedApi(cortiRef);

  const handleAuth = async () => {
    const user = await api.auth({
      access_token,
      refresh_token,
      id_token,
      token_type,
    });
    console.log("Authenticated:", user.email);
  };

  return <CortiEmbeddedReact ref={cortiRef} baseURL="..." />;
}
```

### In vanilla TypeScript / JavaScript

Access API methods through the element reference:

```javascript theme={null}
const element = document.querySelector("corti-embedded");

const user = await element.auth({
  access_token,
  refresh_token,
  id_token,
  token_type,
});
console.log("Authenticated:", user.email);
```

<Note>
  The Web Component and React wrapper use the package API. Window API and PostMessage often wrap the same operation in a payload object instead.
</Note>

## Error codes

All API actions may return errors with the following structure:

```typescript theme={null}
{
  message: string,
  code: 'UNAUTHORIZED' | 'NOT_READY' | 'NOT_FOUND' | 'INVALID_PAYLOAD' | 'INTERNAL_ERROR',
  details?: unknown
}
```

| Code              | Description                                  | Common Causes                                                   |
| ----------------- | -------------------------------------------- | --------------------------------------------------------------- |
| `UNAUTHORIZED`    | User is not authenticated or session expired | Must call `auth` first, or session has expired                  |
| `NOT_READY`       | Required precondition not met                | Missing interaction, not in recording session, etc.             |
| `NOT_FOUND`       | Requested resource does not exist            | Invalid interaction ID, user not found                          |
| `INVALID_PAYLOAD` | Request payload validation failed            | Missing required fields, invalid formats, constraint violations |
| `INTERNAL_ERROR`  | Unexpected server or client error            | Retry the request or contact support                            |

***

## Methods

### auth

Authenticate the user session with the embedded Assistant. All payload properties are required and can be found on the response from the authentication service. For convenience, you can simply set the authentication response as the payload directly.

**Usage:**

```typescript theme={null}
// Get API from hook (React) or element ref
const user = await api.auth({
  access_token: string,
  refresh_token: string,
  id_token: string,
  token_type: string,
});
```

**Prerequisites:** None

**Input validation:**

* All fields (`access_token`, `refresh_token`, `id_token`, `token_type`) are required
* Tokens must be valid JWT strings

**Possible errors:**

* `INVALID_PAYLOAD`: Missing required authentication fields
* `UNAUTHORIZED`: Invalid or expired tokens
* `INTERNAL_ERROR`: Authentication service unavailable

**Returns:**

```typescript theme={null}
{
  id: string,
  email: string
}
```

***

### configure

Configure the Assistant interface for the current session, including toggling UI features, visual appearance, and locale settings.

**Usage:**

```typescript theme={null}
const config = await api.configure({
  features: {
    interactionTitle: boolean,
    aiChat: boolean,
    documentFeedback: boolean,
    navigation: boolean,
    virtualMode: boolean,
    syncDocumentAction: boolean,
    templateEditor: boolean,
  },
  appearance: {
    primaryColor: string | null,
  },
  locale: {
    interfaceLanguage: string | null,
    dictationLanguage: string,
    overrides: Record<string, string>,
  },
});
```

**Prerequisites:** None (can be called anytime)

**Input validation:**

* `appearance.primaryColor`: Must be valid CSS color (hex, rgb, hsl) or `null`
* `locale.interfaceLanguage`: Must be one of the supported interface languages (see Configuration Reference) or `null`
* `locale.dictationLanguage`: Must be one of the supported dictation languages (see Configuration Reference)
* `locale.overrides`: Keys must match known override strings (see Configuration Reference)
* `features.*`: Must be boolean values
* `network.websocketBaseUrl`: Must be a valid URL if provided (typically `wss://` in production)

**Possible errors:**

* `INVALID_PAYLOAD`: Invalid color format, unsupported language code, non-boolean feature flags
* `INTERNAL_ERROR`: Failed to apply configuration

**Returns:**

```typescript theme={null}
{
  features: {
    interactionTitle: boolean,
    aiChat: boolean,
    documentFeedback: boolean,
    navigation: boolean,
    virtualMode: boolean,
    syncDocumentAction: boolean,
    templateEditor: boolean,
  },
  appearance: {
    primaryColor: string | null,
  },
  locale: {
    interfaceLanguage: string | null,
    dictationLanguage: string,
    overrides: Record<string, string>,
  }
}
```

**Defaults:**

* `features.interactionTitle: true`
* `features.aiChat: true`
* `features.documentFeedback: true`
* `features.navigation: false`
* `features.virtualMode: true`
* `features.syncDocumentAction: false`
* `features.templateEditor: true`
* `appearance.primaryColor: null` (uses built-in styles)
* `locale.interfaceLanguage: null` (uses user's default or browser setting)
* `locale.dictationLanguage: "en"`
* `locale.overrides: {}`

**Note:** The command can be invoked with a partial object, and only the specified properties will take effect. Returns the full currently applied configuration object.

***

### createInteraction

Create a new interaction session.

**Usage:**

```typescript theme={null}
const interaction = await api.createInteraction({
  assignedUserId: null,
  encounter: {
    identifier: `encounter-${Date.now()}`,
    status: "planned",
    type: "first_consultation",
    period: {
      startedAt: new Date().toISOString(),
    },
    title: "Initial Consultation",
  },
});
```

**Prerequisites:** User must be authenticated (`auth` must be called first)

**Input validation:**

* `encounter.identifier`: Required, non-empty string
* `encounter.status`: Must be one of: `"planned"`, `"in-progress"`, `"completed"`, `"cancelled"`
* `encounter.type`: Must be one of: `"ambulatory"`, `"emergency"`, `"field"`, `"first_consultation"`, `"home_health"`, `"inpatient_encounter"`, `"short_stay"`, `"virtual"`
* `encounter.period.startedAt`: Required, must be valid ISO 8601 datetime string
* `encounter.title`: Optional string
* `assignedUserId`: Optional string or `null`
* `patient`: Optional object with patient demographic information
  * `patient.identifier`: Optional string (patient identifier from external system)
  * `patient.name`: Optional string (patient's full name)
  * `patient.gender`: Optional, must be one of: `"male"`, `"female"`, `"other"`, `"unknown"`
  * `patient.birthDate`: Optional string or `null` (ISO 8601 date format)
  * `patient.pronouns`: Optional string (preferred pronouns)

**Possible errors:**

* `UNAUTHORIZED`: User not authenticated, call `auth` first
* `INVALID_PAYLOAD`: Missing required fields, invalid encounter status/type, invalid date format
* `INTERNAL_ERROR`: Failed to create interaction

**Returns:**

```typescript theme={null}
{
  id: string,
  createdAt: string,
  status?: string
}
```

***

### addFacts

Add contextual facts to the current interaction.

**Usage:**

```typescript theme={null}
await api.addFacts([
  { text: "Chest pain", group: "other" },
  { text: "Shortness of breath", group: "other" },
  { text: "Fatigue", group: "other" },
]);
```

**Prerequisites:**

* User must be authenticated
* An interaction must exist (call `createInteraction` first)

**Input validation:**

* Web Component / React: pass an array of facts
* Window API / PostMessage: pass `{ facts: [...] }`
* `facts[].text`: Required, non-empty string
* `facts[].group`: Optional string, defaults to `"other"` if not provided
* `facts[].source`: Optional, defaults to `"user"`

**Possible errors:**

* `NOT_READY`: No active interaction, call `createInteraction` first
* `UNAUTHORIZED`: User not authenticated
* `INVALID_PAYLOAD`: Empty facts array, missing text field
* `INTERNAL_ERROR`: Failed to save facts

**Returns:** `void`

#### Patient gender

In languages where patient gender affects phrasing in documentation (e.g., pronoun usage), explicitly passing patient gender helps prevent incorrect assumptions when Corti cannot reliably infer it from the data collected throughout the consultation. This helps maintain consistent pronouns and narrative wording.

For best results, provide both:

1. Structured field: `patient.gender` in `createInteraction` (`"male"`, `"female"`, `"other"`, or `"unknown"`)
2. Language fact: a clear sentence in the target document language passed to `addFacts`

Common German examples:

```text theme={null}
Das Geschlecht des Patienten ist männlich.
Das Geschlecht des Patienten ist weiblich.
Das Geschlecht des Patienten ist divers.
Das Geschlecht des Patienten ist unbekannt.
```

Full flow example for a `male` patient:

```javascript theme={null}
const api = window.CortiEmbedded.v1;
await api.auth({
  /* auth here */
});
await api.configure({ locale: { interfaceLanguage: "de-DE" } });
const interaction = await api.createInteraction({
  assignedUserId: null,
  encounter: {
    identifier: `encounter-${Date.now()}`,
    status: "planned",
    type: "first_consultation",
    period: {
      startedAt: new Date().toISOString(),
    },
    title: "Erstkonsultation",
  },
  patient: {
    identifier: "PATIENT-123",
    name: "Max Mustermann",
    gender: "male",
  },
});
await api.navigate({ path: `/session/${interaction.id}` });
await api.addFacts({
  facts: [{ text: "Das Geschlecht des Patienten ist männlich." }],
});
```

***

### configureSession

Set session-level defaults and preferences. **This method will not overwrite defaults set by the user.**

<Note>
  `defaultTemplateKey` and `defaultOutputLanguage` must be provided together. If one is missing, the method returns `INVALID_PAYLOAD`.
</Note>

<Info>
  `defaultOutputLanguage` has no effect on its own. It is only used together with `defaultTemplateKey` to resolve the template.
</Info>

<Tip>
  `getTemplates` returns language-specific IDs (for example, `"corti-soap-en"`). For `configureSession`, split this into: `defaultTemplateKey: "corti-soap"` and `defaultOutputLanguage: "en"`.
</Tip>

**Usage:**

```typescript theme={null}
await api.configureSession({
  defaultLanguage: "en",
  defaultOutputLanguage: "en",
  defaultTemplateKey: "corti-soap",
  defaultMode: "virtual",
});
```

```javascript theme={null}
// If getTemplates().templates[i].id is "corti-soap-en"
await api.configureSession({
  defaultTemplateKey: "corti-soap",
  defaultOutputLanguage: "en",
});
```

**Prerequisites:** User must be authenticated

**Input validation:**

* `defaultLanguage`: Must be valid language code (e.g., `"en-US"`, `"da-DK"`)
* `defaultOutputLanguage`: Must be valid language code
* `defaultTemplateKey`: Must be a language-agnostic template identifier
* `defaultMode`: Must be either `"virtual"` or `"in-person"`
* All fields are optional, but if either `defaultTemplateKey` or `defaultOutputLanguage` is provided, both must be provided together
* `defaultTemplateKey` and `defaultOutputLanguage` must be set together

**Possible errors:**

* `UNAUTHORIZED`: User not authenticated
* `INVALID_PAYLOAD`: Invalid payload (including when only one of `defaultTemplateKey` or `defaultOutputLanguage` is provided)
* `NOT_FOUND`: No template matches `defaultTemplateKey` + `defaultOutputLanguage`. Call `getTemplates` first to verify the template exists for the selected language.
* `INTERNAL_ERROR`: Failed to update session settings

**Returns:** `void`

***

### navigate

Navigate to a specific path within the embedded Assistant.

**Usage:**

```typescript theme={null}
await api.navigate("/session/interaction-123");
```

**Prerequisites:** None

**Input validation:**

* Web Component / React: pass the path string directly
* Window API / PostMessage: pass `{ path: "/..." }`
* `path`: Required, must start with `/`
* `path`: Cannot be a full URL (no `http://`, `https://`, or `//` protocol)
* `path`: Must be a relative path within the application

**Valid path patterns:**

* `/` – Root/home
* `/session/<id>` – Specific session
* `/templates` – Template browser
* `/settings/*` – Settings pages

**Possible errors:**

* `INVALID_PAYLOAD`:
  * Path does not start with `/` → `"Path must be a relative path starting with '/'"`
  * Path is a full URL → `"Path must be a relative path, not a full URL"`
* `INTERNAL_ERROR`: Navigation failed

**Returns:** `void`

**Navigable URLs:**

* `/` – start a new session
* `/session/<id>` - go to an existing session identified by `<id>`
* `/templates` - browse and create templates
* `/settings/preferences` - edit defaults like languages and default session settings
* `/settings/input` - edit dictation input settings
* `/settings/account` - edit general account settings
* `/settings/archive` - view items in and restore from archive (only relevant if navigation is visible)

***

### setCredentials

Change the credentials of the currently authenticated user. Can be used to set credentials for a user without a password (if only authenticated via identity provider) or to change the password of a user with an existing password.

**Password policy:**

* At least 1 uppercase, 1 lowercase, 1 numerical and 1 special character
* At least 8 characters long

**Usage:**

```typescript theme={null}
await api.setCredentials({ password: "YOUR_NEW_PASSWORD" });
```

**Prerequisites:** User must be authenticated

**Input validation:**

* `password`: Required string
* Password must meet policy requirements:
  * Minimum 8 characters
  * At least 1 uppercase letter (A-Z)
  * At least 1 lowercase letter (a-z)
  * At least 1 number (0-9)
  * At least 1 special character

**Possible errors:**

* `UNAUTHORIZED`: User not authenticated
* `INVALID_PAYLOAD`:
  * Password too short → `"Password does not meet requirements"`
  * Missing required character types → `"Password does not meet requirements"`
* `INTERNAL_ERROR`: Failed to update password

**Returns:** `void`

***

### startRecording

Start recording within the embedded session.

**Usage:**

```typescript theme={null}
await api.startRecording();
```

**Prerequisites:**

* User must be authenticated (call `auth`)
* An interaction must exist (call `createInteraction`)
* Application must be in an interview/session context

**Input validation:** None (no payload required)

**Possible errors:**

* `NOT_READY`:
  * `"Must be in an interview to start recording"` – Not in interview context
  * `"No interaction ID found. Call createInteraction first"` – No active interaction
* `UNAUTHORIZED`:
  * `"Not authenticated. Call auth first"` – No valid session
* `NOT_FOUND`: `"Interaction not found"` – Interaction ID is invalid
* `INTERNAL_ERROR`: Failed to connect to recording service (WebSocket error)

**Returns:** `void`

***

### stopRecording

Stop recording within the embedded session.

**Usage:**

```typescript theme={null}
await api.stopRecording();
```

**Prerequisites:** Must be actively recording (call `startRecording` first)

**Input validation:** None (no payload required)

**Possible errors:**

* `NOT_READY`: `"Must be in an interview to stop recording"` – Not in active recording session
* `INTERNAL_ERROR`: Failed to disconnect from recording service

**Returns:** `void`

***

### getStatus

Request information about the current state of the application, including authentication status, current user, current URL and interaction details.

**Usage:**

```typescript theme={null}
const status = await api.getStatus();
```

**Prerequisites:** None (always available)

**Input validation:** None (no payload required)

**Notes:**

* This action does not throw structured error codes
* Very rare, typically always succeeds
* May return partial data if specific queries fail (e.g., `interaction` will be `null` if fetch fails)

**Returns:**

```typescript theme={null}
{
  auth: {
    isAuthenticated: boolean,
    user: {
      id: string,
      email: string
    } | null
  },
  currentUrl: string,
  interaction: {
    id: string,
    title: string,
    state: "planned" | "ongoing" | "paused" | "disconnected" | "ending" | "parsing" | "ended",
    startedAt: string,
    endedAt: string | null,
    endsAt: string | null,
    transcripts: Array<{
      utterances: Array<{
        id: string,
        start: number,
        duration: number,
        text: string,
        isFinal: boolean,
        participantId: string | undefined,
      }>,
      participants: Array<{
        id: string,
        channel: number,
        role: "agent" | "patient" | "other" | "multiple"
      }>,
      isMultiChannel: boolean
    }>,
    documents: Array<{
      id: string,
      name: string,
      templateRef: string,
      isStream: boolean,
      sections: Array<{
        key: string,
        name: string,
        text: string,
        sort: number,
        createdAt: string,
        updatedAt: string,
        markdown: string | undefined | null,
        htmlText: string | undefined,
        plainText: string | undefined,
      }>,
      outputLanguage: string,
    }>,
    facts: Array<{
      id: string,
      text: string,
      group: string,
      isDiscarded: boolean,
      source: "core" | "system" | "user",
      createdAt: string | undefined,
      updatedAt: string,
      isNew: boolean,
      isDraft: boolean | undefined,
    }>,
    websocketUrl: string
  } | null
}
```

***

### getTemplates

Retrieve all document templates available to the authenticated user. This includes both built-in templates provided by Corti and custom templates created by the user themself.

<Tip>
  Use this method before [`configureSession`](#configuresession) to verify the template and language combination you want to set as default.
</Tip>

**Usage:**

```typescript theme={null}
const response = await api.getTemplates();
console.log(response.templates); // Array of available templates
```

**Prerequisites:** User must be authenticated (`auth` must be called first)

**Input validation:** None (no payload required)

**Possible errors:**

* `UNAUTHORIZED`: User not authenticated, call `auth` first
* `INTERNAL_ERROR`: Failed to fetch templates from server

**Returns:**

```typescript theme={null}
{
  templates: Array<{
    id: string; // Language-specific ID (for example, "corti-soap-en")
    name: string;
    description?: string;
    language: {
      code: string;
      name: string;
      locale?: string;
    };
    sections: Array<{
      id: string;
      title: string;
    }>;
    isCustom: boolean;
  }>;
}
```

**Example response:**

```json theme={null}
{
  "templates": [
    {
      "id": "corti-soap-en",
      "name": "SOAP Note",
      "description": "Standard SOAP format for clinical documentation",
      "language": {
        "code": "en",
        "name": "English",
        "locale": "en-US"
      },
      "sections": [
        { "id": "subjective", "title": "Subjective" },
        { "id": "objective", "title": "Objective" },
        { "id": "assessment", "title": "Assessment" },
        { "id": "plan", "title": "Plan" }
      ],
      "isCustom": false
    },
    {
      "id": "custom-template-123",
      "name": "Emergency Department Note",
      "description": "Custom template for ED visits",
      "language": {
        "code": "en",
        "name": "English"
      },
      "sections": [
        { "id": "chief-complaint", "title": "Chief Complaint" },
        { "id": "hpi", "title": "History of Present Illness" },
        { "id": "treatment", "title": "Treatment & Disposition" }
      ],
      "isCustom": true
    }
  ]
}
```

**Use cases:**

* Display a template picker UI for users to select their preferred documentation template
* Filter templates by language to match the current session settings
* Distinguish between built-in and custom templates using the `isCustom` flag
* Pre-populate template selection based on user preferences or defaults

***

## Common workflows

### Initialize and start recording

```typescript theme={null}
// Using the Web Component API (via hook or ref)
// const api = useCortiEmbeddedApi(cortiRef); // React
// or: const api = element; // Vanilla JS

try {
  // 1. Authenticate
  const user = await api.auth({
    access_token: "...",
    refresh_token: "...",
    id_token: "...",
    token_type: "Bearer",
  });
  console.log("Authenticated as:", user.email);

  // 2. Configure app (optional)
  await api.configure({
    features: { virtualMode: true },
    locale: { dictationLanguage: "en-US" },
  });

  // 3. Create interaction
  const interaction = await api.createInteraction({
    encounter: {
      identifier: "enc-123",
      status: "planned",
      type: "ambulatory",
      period: { startedAt: new Date().toISOString() },
      title: "Patient Visit",
    },
  });
  console.log("Created interaction:", interaction.id);

  // 4. Navigate to session page
  await api.navigate(`/session/${interaction.id}`);
  console.log("Navigated to session");

  // 5. Start recording
  await api.startRecording();
  console.log("Recording started");
} catch (error) {
  console.error("Workflow failed:", error.message, error.code);
}
```

### Error handing best practice

```typescript theme={null}
// Assuming api is already available from hook or ref

async function startRecordingWithRetry() {
  try {
    await api.startRecording();
  } catch (error) {
    switch (error.code) {
      case "UNAUTHORIZED":
        // Re-authenticate user
        console.log("Session expired, re-authenticating...");
        await reauthenticate();
        await api.startRecording(); // Retry
        break;

      case "NOT_READY":
        // Ensure prerequisites are met
        if (error.message.includes("createInteraction")) {
          console.log("Creating interaction first...");
          await api.createInteraction({
            encounter: {
              identifier: `enc-${Date.now()}`,
              status: "planned",
              type: "ambulatory",
              period: { startedAt: new Date().toISOString() },
            },
          });
          await api.startRecording(); // Retry
        } else if (error.message.includes("interview")) {
          console.error("Must be in interview context");
          // Navigate user to session page or show error
        }
        break;

      case "INTERNAL_ERROR":
        // Retry once after delay
        console.log("Internal error, retrying...");
        await new Promise((resolve) => setTimeout(resolve, 2000));
        try {
          await api.startRecording();
        } catch (retryError) {
          console.error("Retry failed:", retryError.message);
          // Show error to user
        }
        break;

      default:
        console.error("Unexpected error:", error);
    }
  }
}
```

### Complete session lifecycle

```typescript theme={null}
// Assuming api is already available from hook or ref
let currentInteractionId = null;

async function initializeSession() {
  // Authenticate
  await api.auth({
    /* tokens */
  });

  // Configure
  await api.configure({
    features: {
      virtualMode: true,
      aiChat: true,
    },
  });

  // Set defaults
  await api.configureSession({
    defaultLanguage: "en-US",
    defaultMode: "virtual",
  });
}

async function startNewInteraction(encounterData) {
  const interaction = await api.createInteraction({
    encounter: encounterData,
  });
  currentInteractionId = interaction.id;

  // Add initial context
  await api.addFacts([
    { text: "Chief complaint: Headache", group: "symptoms" },
  ]);

  await api.startRecording();
  return interaction;
}

async function endInteraction() {
  await api.stopRecording();

  // Get final status
  const status = await api.getStatus();
  return status.interaction;
}

// Usage
await initializeSession();
const interaction = await startNewInteraction({
  identifier: "enc-001",
  status: "planned",
  type: "ambulatory",
  period: { startedAt: new Date().toISOString() },
  title: "Follow-up Visit",
});

// ... conduct session ...

const finalInteraction = await endInteraction();
console.log("Session ended:", finalInteraction);
```

## Configuration reference

### Available interface languages

<Note>
  Updated February 2026
</Note>

| Language code | Language          |
| ------------- | ----------------- |
| `en`          | English           |
| `de-DE`       | German            |
| `fr-FR`       | French            |
| `it-IT`       | Italian           |
| `sv-SE`       | Swedish           |
| `da-DK`       | Danish            |
| `nb-NO`       | Norwegian Bokmål  |
| `nn-NO`       | Norwegian Nynorsk |

### Available Dictation Languages

<Note>
  Updated February 2026
</Note>

#### EU

| Language code | Language        |
| ------------- | --------------- |
| `en`          | English         |
| `en-GB`       | British English |
| `de`          | German          |
| `fr`          | French          |
| `sv`          | Swedish         |
| `da`          | Danish          |
| `nl`          | Dutch           |
| `no`          | Norwegian       |

#### US

| Language code | Language |
| ------------- | -------- |
| `en`          | English  |

### Known strings to override

Currently, only the following keys are exposed for override:

| Key                                     | Default value            | Purpose                                                             |
| --------------------------------------- | ------------------------ | ------------------------------------------------------------------- |
| `interview.document.syncDocument.label` | *"Synchronize document"* | The button text for the *"synchronize document"* button if enabled. |

## Appearance configuration

<Note>
  Disclaimer - always ensure WCAG 2.2 AA conformance
</Note>

Corti Assistant's default theme has been evaluated against WCAG 2.2 Level AA and meets applicable success criteria in our supported browsers.

This conformance claim applies only to the default configuration. Customer changes (e.g., color palettes, CSS overrides, third-party widgets, or content) are outside the scope of this claim. Customers are responsible for ensuring their customizations continue to meet WCAG 2.2 AA (including color contrast and focus visibility).

When supplying a custom accent or theme, Customers must ensure WCAG 2.2 AA conformance, including:

* 1.4.3 Contrast (Minimum): normal text ≥ 4.5:1; large text ≥ 3:1
* 1.4.11 Non-text Contrast: UI boundaries, focus rings, and selected states ≥ 3:1
* 2.4.11 Focus Not Obscured (Minimum): focus indicators remain visible and unobstructed

Corti provides accessible defaults. If you override them, verify contrast for all states (default, hover, active, disabled, focus) and on all backgrounds you use.

## Related documentation

* [PostMessage API](/assistant/postmessage-api) - Learn how to use the PostMessage integration method
* [Window API](/assistant/window-api) - Learn how to use the Window API integration method
* [Welcome](/assistant/welcome) - Overview of Corti Assistant and integration options

<Note>
  Please [contact us](https://help.corti.app) for help or questions.
</Note>
