Corti.Sdk package exports two main entry points:
| Export | Namespace | Purpose |
|---|---|---|
CortiClient | using Corti; | Full API client with all resource groups, authentication, and WebSockets |
CustomAuthClient | using Corti; | Standalone authentication client for token management and OAuth flows |
CortiClient
The main client for all Corti API operations.Constructors
// 1. Tenant + environment + auth (most common)
new CortiClient(string tenantName, CortiEnvironmentInput environment, CortiClientAuth auth, CortiRequestOptions? requestOptions = null)
// 2. Bearer only — tenant and environment decoded from the JWT
new CortiClient(CortiClientBearerAuth auth, CortiRequestOptions? requestOptions = null)
// 3. Environment only — proxy / passthrough, no SDK-managed auth
new CortiClient(CortiEnvironmentInput environment, CortiRequestOptions? requestOptions = null)
CortiEnvironmentInput accepts a region string, a CortiClientEnvironment, or CortiEnvironments.FromBaseUrl(...) via implicit conversion.
Overload 2 decodes tenant and environment from the access token JWT. If the token cannot be decoded, use overload 1 instead.
Overload 3 sends no Authorization header. CreateStreamApiAsync / CreateTranscribeApiAsync require a tenant and will throw. See Proxy / passthrough.
CortiRequestOptions
| Property | Type | Default | Description |
|---|---|---|---|
MaxRetries | int? | 2 | Number of automatic retries on 408, 429, and 5xx |
Timeout | TimeSpan? | 30s | Default request timeout |
HttpClient | HttpClient? | null | Custom HttpClient instance |
AdditionalHeaders | IEnumerable<KeyValuePair<string, string?>>? | null | Headers sent with every request |
Request options
Every HTTP method accepts an optionalRequestOptions parameter:
C# .NET
using System.Collections.Generic;
using Corti;
await client.Interactions.ListAsync(
new InteractionsListRequest(),
new RequestOptions
{
Timeout = TimeSpan.FromSeconds(30),
MaxRetries = 3,
AdditionalHeaders = new Dictionary<string, string?>
{
["X-Request-Id"] = "abc123",
},
});
| Property | Type | Description |
|---|---|---|
BaseUrl | string? | Override the base URL for this request |
HttpClient | HttpClient? | Override the HttpClient for this request |
MaxRetries | int? | Override the default retry count |
Timeout | TimeSpan? | Override the default timeout |
AdditionalHeaders | IEnumerable<KeyValuePair<string, string?>> | Additional HTTP headers |
AdditionalQueryParameters | IEnumerable<KeyValuePair<string, string>> | Additional query string parameters |
AdditionalBodyProperties | object? | Additional JSON properties merged into the request body |
Resource groups
The client exposes the following resource groups as properties:| Group | Description | API endpoints |
|---|---|---|
client.Interactions | Manage patient encounters and interaction sessions | Interactions API |
client.Recordings | Upload and retrieve audio recordings for interactions | Recordings API |
client.Languages | List available languages and enabled endpoint details | Languages |
client.Transcripts | Create and retrieve transcriptions of recordings | Transcripts API |
client.Documents.GenerateAsync | Generate a clinical document from templates or dynamic definitions | Guided Synthesis |
client.Documents.Templates | Create, version, and publish guided document templates | Template Creation |
client.Documents.Sections | Create, version, and publish guided document sections | Section Creation |
client.Documents | Interaction-scoped document CRUD | Documents Classic |
client.Facts | Extract and manage structured clinical facts | Facts API |
client.Templates | List and retrieve classic document generation templates | Templates API |
client.Codes | Predict medical codes from clinical data | Codes API |
client.Agents | Create and interact with AI agents | Agents API |
client.Auth | OAuth token management and authorization URLs | Auth API |
| Method | Description | API endpoint |
|---|---|---|
CreateStreamApiAsync(interactionId) | Real-time WebSocket streaming (transcription + facts) | Stream API |
CreateTranscribeApiAsync() | Real-time WebSocket speech-to-text (standalone) | Transcribe API |
Interactions
Manage interaction sessions that group recordings, transcripts, documents, and facts together.C# .NET
using Corti;
// List interactions (pager — see Pagination)
var pager = await client.Interactions.ListAsync(new InteractionsListRequest());
// Create a new interaction
var response = await client.Interactions.CreateAsync(
new InteractionsCreateRequest
{
Encounter = new InteractionsEncounterCreateRequest
{
Identifier = "my-encounter-id",
Status = InteractionsEncounterStatusEnum.Planned,
Type = InteractionsEncounterTypeEnum.FirstConsultation,
},
});
var interactionId = response.InteractionId;
// Get a specific interaction
var interaction = await client.Interactions.GetAsync(interactionId);
// Update an interaction
await client.Interactions.UpdateAsync(
interactionId,
new InteractionsUpdateRequest
{
Encounter = new InteractionsEncounterUpdateRequest
{
Status = InteractionsEncounterStatusEnum.InProgress,
},
});
// Delete an interaction
await client.Interactions.DeleteAsync(interactionId);
| Method | Parameters | Returns |
|---|---|---|
ListAsync(request) | Filter and pagination options | Pager (async enumerable) |
CreateAsync(request) | Interaction definition | Created interaction |
GetAsync(id) | Interaction UUID | Single interaction |
UpdateAsync(id, request?) | Interaction UUID + update fields | Updated interaction |
DeleteAsync(id) | Interaction UUID | void |
Recordings
Upload and manage audio recordings within an interaction.C# .NET
using Corti;
// Upload a recording
var recording = await client.Recordings.UploadAsync(
interactionId,
File.OpenRead("audio.mp3"));
var recordingId = recording.RecordingId;
// List recordings for an interaction
var recordings = await client.Recordings.ListAsync(interactionId);
// Download a recording
var stream = await client.Recordings.GetAsync(interactionId, recordingId);
// Delete a recording
await client.Recordings.DeleteAsync(interactionId, recordingId);
| Method | Parameters | Returns |
|---|---|---|
UploadAsync(interactionId, file) | Interaction UUID + file stream | Created recording |
ListAsync(interactionId) | Interaction UUID | List of recordings |
GetAsync(interactionId, recordingId) | Interaction UUID + recording UUID | Audio stream |
DeleteAsync(interactionId, recordingId) | Interaction UUID + recording UUID | void |
Languages
List available languages and which endpoints support each language.| Method | Parameters | Returns |
|---|---|---|
ListAsync(request?) | Optional LanguagesListRequest.Endpoint filter | LanguagesListResponse |
Transcripts
Create transcriptions from uploaded recordings and retrieve results.C# .NET
using Corti;
// Create a transcript from a recording
var transcript = await client.Transcripts.CreateAsync(
interactionId,
new TranscriptsCreateRequest
{
RecordingId = recordingId,
PrimaryLanguage = "en",
});
var transcriptId = transcript.Id;
// Check transcription status
var status = await client.Transcripts.GetStatusAsync(interactionId, transcriptId);
// List transcripts for an interaction
var transcripts = await client.Transcripts.ListAsync(interactionId);
// Get a specific transcript
var result = await client.Transcripts.GetAsync(interactionId, transcriptId);
// Delete a transcript
await client.Transcripts.DeleteAsync(interactionId, transcriptId);
| Method | Parameters | Returns |
|---|---|---|
CreateAsync(interactionId, request) | Interaction UUID + transcript definition | Created transcript |
GetStatusAsync(interactionId, transcriptId) | Interaction UUID + transcript UUID | Transcription status |
ListAsync(interactionId, request?) | Interaction UUID + optional filters | List of transcripts |
GetAsync(interactionId, transcriptId) | Interaction UUID + transcript UUID | Single transcript |
DeleteAsync(interactionId, transcriptId) | Interaction UUID + transcript UUID | void |
Guided Document Generation
Generate structured clinical documents using guided synthesis. Accepts a template reference, an ad-hoc assembly of sections, or a fully inline dynamic template.| Method | Parameters | Returns |
|---|---|---|
GenerateAsync(request) | GuidedDocumentsGenerateRequest — one of templateRef, assemblyTemplate, or dynamicTemplate | Generated document |
See the Guided Synthesis guide for the four template-supply paths and context options.
Guided Templates
Create, version, and publish document templates that define section composition and generation instructions.| Method | Parameters | Returns |
|---|---|---|
ListAsync(request) | GuidedTemplatesListRequest — optional filters (lang, region, specialty, label, published, source) | List of templates |
CreateAsync(request) | GuidedTemplatesCreateRequest — template definition | Created template |
GetAsync(templateId) | Template UUID | Single template |
UpdateAsync(templateId, request) | Template UUID + GuidedTemplatesUpdateRequest | Updated template |
DeleteAsync(templateId) | Template UUID | void |
Template Versions
| Method | Parameters | Returns |
|---|---|---|
Templates.Versions.ListAsync(templateId) | Template UUID | List of versions |
Templates.Versions.CreateAsync(templateId, request) | Template UUID + GuidedTemplatesCreateVersionRequest | Created version |
Templates.Versions.GetAsync(templateId, versionId) | Template UUID + version UUID | Single version |
Templates.Versions.DeleteAsync(templateId, versionId) | Template UUID + version UUID | void |
Templates.Versions.PublishAsync(templateId, versionId) | Template UUID + version UUID | Status response |
Guided Sections
Create, version, and publish document sections that define individual clinical note components with structured output schemas.| Method | Parameters | Returns |
|---|---|---|
ListAsync(request) | GuidedSectionsListRequest — optional filters (lang, region, specialty, label, published, source) | List of sections |
CreateAsync(request) | GuidedSectionsCreateRequest — section definition | Created section |
GetAsync(sectionId) | Section UUID | Single section |
UpdateAsync(sectionId, request) | Section UUID + GuidedSectionsUpdateRequest | Updated section |
DeleteAsync(sectionId) | Section UUID | void |
Section Versions
| Method | Parameters | Returns |
|---|---|---|
Sections.Versions.ListAsync(sectionId) | Section UUID | List of versions |
Sections.Versions.CreateAsync(sectionId, request) | Section UUID + GuidedSectionsCreateVersionRequest | Created version |
Sections.Versions.GetAsync(sectionId, versionId) | Section UUID + version UUID | Single version |
Sections.Versions.DeleteAsync(sectionId, versionId) | Section UUID + version UUID | void |
Sections.Versions.PublishAsync(sectionId, versionId) | Section UUID + version UUID | Status response |
C# .NET
using Corti;
// --- Templates ---
// List templates (with optional filters)
var templates = await client.Documents.Templates.ListAsync(
new GuidedTemplatesListRequest { Lang = new[] { "en" }, Published = true });
// Create a template from scratch
var template = await client.Documents.Templates.CreateAsync(
new GuidedTemplatesCreateFromScratchRequest
{
Name = "My Template",
Description = "Custom SOAP note",
Lang = "en",
Sections = new[] { new GuidedTemplateSectionRef { SectionId = "<section-uuid>", Order = 0 } },
});
// Get / update / delete a template
var tmpl = await client.Documents.Templates.GetAsync(templateId);
await client.Documents.Templates.UpdateAsync(templateId,
new GuidedTemplatesUpdateRequest { Name = "Renamed" });
await client.Documents.Templates.DeleteAsync(templateId);
// --- Template Versions ---
var versions = await client.Documents.Templates.Versions.ListAsync(templateId);
var version = await client.Documents.Templates.Versions.CreateAsync(templateId,
new GuidedTemplatesCreateVersionRequest
{
Sections = new[] { new GuidedTemplateSectionRef { SectionId = "<section-uuid>", Order = 0 } },
});
await client.Documents.Templates.Versions.PublishAsync(templateId, versionId);
await client.Documents.Templates.Versions.DeleteAsync(templateId, versionId);
// --- Sections ---
var sections = await client.Documents.Sections.ListAsync(
new GuidedSectionsListRequest { Lang = new[] { "en" } });
var section = await client.Documents.Sections.CreateAsync(
new GuidedSectionsCreateFromScratchRequest
{
Name = "HPI",
Generation = new GuidedSectionGeneration
{
Heading = "History of Present Illness",
Instructions = new GuidedSectionInstructions { ContentPrompt = "Summarize the patient history" },
OutputSchema = new GuidedStringNode(),
},
});
await client.Documents.Sections.UpdateAsync(sectionId,
new GuidedSectionsUpdateRequest { Name = "Renamed" });
await client.Documents.Sections.DeleteAsync(sectionId);
// --- Section Versions ---
var sectionVersions = await client.Documents.Sections.Versions.ListAsync(sectionId);
await client.Documents.Sections.Versions.PublishAsync(sectionId, versionId);
// --- Generate ---
var result = await client.Documents.GenerateAsync(
new GuidedDocumentsGenerateByTemplateRef
{
OutputLanguage = "en-US",
InteractionId = "<interaction-uuid>",
TemplateRef = new GuidedTemplateRef { TemplateId = "<template-uuid>" },
});
Documents (Classic)
These interaction-scoped methods are superseded by Guided Document Generation via
client.Documents.GenerateAsync(). Migrate to the guided API for new integrations.C# .NET
using Corti;
// Generate a document
var document = await client.Documents.CreateAsync(
interactionId,
new DocumentsCreateRequestWithTemplateKey
{
TemplateKey = "corti-soap",
OutputLanguage = "en",
Context = new[]
{
new DocumentsContextWithFacts
{
Type = DocumentsContextWithFactsType.Facts,
Data = new[]
{
new FactsContext { Text = "Patient reports persistent headache for 3 days", Source = CommonSourceEnum.Core },
new FactsContext { Text = "No history of migraines", Source = CommonSourceEnum.User },
},
},
},
});
var documentId = document.Id;
// List documents
var documents = await client.Documents.ListAsync(interactionId);
// Get a specific document
var doc = await client.Documents.GetAsync(interactionId, documentId);
// Update a document
await client.Documents.UpdateAsync(
interactionId,
documentId,
new DocumentsUpdateRequest { Name = "Updated note" });
// Delete a document
await client.Documents.DeleteAsync(interactionId, documentId);
| Method | Parameters | Returns |
|---|---|---|
CreateAsync(interactionId, request) | Interaction UUID + document generation options | Generated document |
ListAsync(interactionId) | Interaction UUID | List of documents |
GetAsync(interactionId, documentId) | Interaction UUID + document UUID | Single document |
UpdateAsync(interactionId, documentId, request?) | Interaction UUID + document UUID + update fields | Updated document |
DeleteAsync(interactionId, documentId) | Interaction UUID + document UUID | void |
Facts
Extract structured clinical facts from text or manage facts on an interaction.C# .NET
using Corti;
// Extract facts from text (standalone)
var extracted = await client.Facts.ExtractAsync(
new FactsExtractRequest
{
Context = new[]
{
new CommonTextContext
{
Type = new CommonTextContext.TypeLiteral(),
Text = "Patient has a temperature of 38.5°C and reports headache.",
},
},
OutputLanguage = "en",
});
// List facts for an interaction
var facts = await client.Facts.ListAsync(interactionId);
// Create facts on an interaction
var created = await client.Facts.CreateAsync(
interactionId,
new FactsCreateRequest
{
Facts = new[]
{
new FactsCreateInput { Text = "Temperature 38.5°C", Group = "vitals" },
},
});
// Update a single fact
await client.Facts.UpdateAsync(
interactionId,
factId,
new FactsUpdateRequest { Text = "Temperature 39.0°C" });
// List available fact groups
var groups = await client.Facts.FactGroupsListAsync();
| Method | Parameters | Returns |
|---|---|---|
ExtractAsync(request) | Extraction options (context, output language) | Extracted facts |
ListAsync(interactionId) | Interaction UUID | List of facts |
CreateAsync(interactionId, request) | Interaction UUID + fact definitions | Created facts |
BatchUpdateAsync(interactionId, request) | Interaction UUID + fact updates | Updated facts |
UpdateAsync(interactionId, factId, request?) | Interaction UUID + fact ID + update fields | Updated fact |
FactGroupsListAsync() | None | Available fact group definitions |
Templates
List and inspect document generation templates available to your tenant.C# .NET
using Corti;
// List all templates
var templates = await client.Templates.ListAsync(new TemplatesListRequest());
// Get a specific template by key
var template = await client.Templates.GetAsync("corti-soap");
// List template sections
var sections = await client.Templates.SectionListAsync(new TemplatesSectionListRequest());
| Method | Parameters | Returns |
|---|---|---|
ListAsync(request) | List filters | List of templates |
GetAsync(key) | Template key string | Single template |
SectionListAsync(request) | Section list filters | List of template sections |
Codes
Predict medical codes from clinical data.C# .NET
var response = await client.Codes.PredictAsync(new CodesGeneralPredictRequest
{
System = [CommonCodingSystemEnum.Icd10CmInpatient],
Context =
[
new CommonTextContext
{
Type = new CommonTextContext.TypeLiteral(),
Text = "Progress Note — Day 3: Patient continues on IV vancomycin for MRSA bacteremia. Blood cultures from yesterday still pending. Acute kidney injury improving — creatinine down to 1.8 from 2.4. Patient also has history of CHF, currently euvolemic on home dose of furosemide. Diabetes managed with insulin sliding scale, glucose well controlled.",
},
],
});
| Method | Parameters | Returns |
|---|---|---|
PredictAsync(request) | CodesGeneralPredictRequest (text, code system) | Code predictions |
Agents
Create and interact with AI agents (Agentic Framework).C# .NET
using Corti;
// List agents
var agents = await client.Agents.ListAsync(new AgentsListRequest());
// Create an agent
var agent = await client.Agents.CreateAsync(
new AgentsCreateAgent
{
Name = "My Agent",
Description = "A helpful assistant",
});
// Get agent details
var details = await client.Agents.GetAsync(agent.Id);
// Send a message to an agent
var response = await client.Agents.MessageSendAsync(
agent.Id,
new AgentsMessageSendParams
{
Message = new AgentsMessage
{
Role = AgentsMessageRole.User,
Kind = AgentsMessageKind.Message,
MessageId = $"msg-{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}",
Parts = new[]
{
AgentsPart.FromAgentsTextPart(
new AgentsTextPart { Kind = AgentsTextPartKind.Text, Text = "Hello" }),
},
},
});
// Update an agent
await client.Agents.UpdateAsync(agent.Id, new AgentsUpdateAgent { Description = "Updated" });
// Delete an agent
await client.Agents.DeleteAsync(agent.Id);
| Method | Parameters | Returns |
|---|---|---|
ListAsync(request) | List filters | List of agents |
CreateAsync(request) | Agent definition | Created agent |
GetAsync(id) | Agent ID | Agent details |
GetCardAsync(id) | Agent ID | Agent card (A2A format) |
MessageSendAsync(id, request) | Agent ID + message payload | Agent response |
GetTaskAsync(id, taskId, request?) | Agent ID + task ID | Task details |
GetContextAsync(id, contextId, request?) | Agent ID + context ID | Context details |
GetRegistryExpertsAsync(request?) | Optional filters | Registry experts |
UpdateAsync(id, request?) | Agent ID + update fields | Updated agent |
DeleteAsync(id) | Agent ID | void |
Stream
Real-time WebSocket connection for combined transcription, fact extraction, and more — tied to an interaction.C# .NET
var stream = await client.CreateStreamApiAsync(interactionId);
stream.StreamTranscriptMessage.Subscribe(message =>
{
Console.WriteLine($"Transcript: {message.Data.Text}");
});
stream.StreamFactsMessage.Subscribe(_ =>
{
Console.WriteLine("Facts received");
});
await stream.ConnectAsync(new StreamConfig
{
Transcription = new StreamConfigTranscription
{
PrimaryLanguage = "en",
Participants = new[]
{
new StreamConfigParticipant { Channel = 0, Role = StreamConfigParticipantRole.Doctor },
},
},
Mode = new StreamConfigMode
{
Type = StreamConfigModeType.Facts,
OutputLocale = "en",
},
});
await stream.Send(audioBytes);
Factory method
| Parameter | Type | Required | Description |
|---|---|---|---|
interactionId | string | Yes | Interaction UUID to attach the stream to |
Task<IStreamApi>.
ConnectAsync parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
configuration | StreamConfig | No | Stream configuration (language, participants, mode). When provided, the SDK automatically sends the config message once the socket opens and waits for CONFIG_ACCEPTED. If omitted, you must send a config message yourself |
cancellationToken | CancellationToken | No | Cancellation support |
Events
Subscribe to events using the.Subscribe() method on each Event<T> field:
| Event | Type | Description |
|---|---|---|
Connected | Event<Connected> | WebSocket connection established |
Closed | Event<Closed> | WebSocket connection closed |
ExceptionOccurred | Event<Exception> | WebSocket error occurred |
Reconnecting | Event<ReconnectionInfo> | Reconnection attempt in progress |
StreamTranscriptMessage | Event<StreamTranscriptMessage> | Transcript data received |
StreamFactsMessage | Event<StreamFactsMessage> | Facts data received |
StreamFlushedMessage | Event<StreamFlushedMessage> | Audio buffer flushed |
StreamEndedMessage | Event<StreamEndedMessage> | Stream session ended |
StreamUsageMessage | Event<StreamUsageMessage> | Usage metrics |
StreamDeltaUsageMessage | Event<StreamDeltaUsageMessage> | Incremental usage metrics |
StreamErrorMessage | Event<StreamErrorMessage> | Server-side error |
StreamConfigStatusMessage | Event<StreamConfigStatusMessage> | Config accepted or denied |
UnknownMessage | Event<JsonElement> | Unrecognised message type |
Methods
| Method | Description |
|---|---|
ConnectAsync(configuration?, cancellationToken?) | Open the WebSocket connection |
Send(byte[]) | Send binary audio data |
Send(StreamFlushMessage) | Request the server to flush buffered audio |
Send(StreamEndMessage) | Signal end of audio stream |
Send(StreamConfigMessage) | Send a configuration message manually |
CloseAsync(cancellationToken?) | Close the connection. Call Send(new StreamEndMessage()) first and wait for StreamEndedMessage |
DisposeAsync() | Dispose the WebSocket resources |
Transcribe
Real-time WebSocket speech-to-text without an interaction context.C# .NET
var transcribe = await client.CreateTranscribeApiAsync();
transcribe.TranscribeTranscriptMessage.Subscribe(message =>
{
Console.WriteLine($"Transcript: {message.Data.Text}");
});
await transcribe.ConnectAsync(new TranscribeConfig
{
PrimaryLanguage = "en",
AutomaticPunctuation = true,
});
// Send audio data (e.g. from a microphone stream)
await transcribe.Send(audioBytes);
ConnectAsync parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
configuration | TranscribeConfig | No | Transcribe configuration (language, punctuation, commands). When provided, the SDK automatically sends the config message once the socket opens and waits for CONFIG_ACCEPTED. If omitted, you must send a config message yourself |
cancellationToken | CancellationToken | No | Cancellation support |
Events
| Event | Type | Description |
|---|---|---|
Connected | Event<Connected> | WebSocket connection established |
Closed | Event<Closed> | WebSocket connection closed |
ExceptionOccurred | Event<Exception> | WebSocket error occurred |
Reconnecting | Event<ReconnectionInfo> | Reconnection attempt in progress |
TranscribeTranscriptMessage | Event<TranscribeTranscriptMessage> | Transcript data received |
TranscribeCommandMessage | Event<TranscribeCommandMessage> | Command detected |
TranscribeFlushedMessage | Event<TranscribeFlushedMessage> | Audio buffer flushed |
TranscribeEndedMessage | Event<TranscribeEndedMessage> | Session ended |
TranscribeUsageMessage | Event<TranscribeUsageMessage> | Usage metrics |
TranscribeDeltaUsageMessage | Event<TranscribeDeltaUsageMessage> | Incremental usage metrics |
TranscribeErrorMessage | Event<TranscribeErrorMessage> | Server-side error |
TranscribeConfigStatusMessage | Event<TranscribeConfigStatusMessage> | Config accepted or denied |
UnknownMessage | Event<JsonElement> | Unrecognised message type |
Methods
| Method | Description |
|---|---|
ConnectAsync(configuration?, cancellationToken?) | Open the WebSocket connection |
Send(byte[]) | Send binary audio data |
Send(TranscribeFlushMessage) | Request the server to flush buffered audio |
Send(TranscribeEndMessage) | Signal end of audio stream |
Send(TranscribeConfigMessage) | Send a configuration message manually |
CloseAsync(cancellationToken?) | Close the connection. Call Send(new TranscribeEndMessage()) first and wait for TranscribeEndedMessage |
DisposeAsync() | Dispose the WebSocket resources |
- No interaction ID — Transcribe operates standalone via
CreateTranscribeApiAsync()(nointeractionIdparameter) - Different message types — Transcribe delivers transcript, command, flushed, ended, usage,
delta_usage, and error messages, while Stream delivers transcript, facts, flushed, ended, usage,delta_usage, and error
Auth
OAuth token management viaclient.Auth. In most cases you won’t call these directly — the SDK handles tokens automatically based on the auth option you pass to the constructor. These methods are useful for advanced scenarios like generating authorization URLs for browser-based flows.
| Method | Description |
|---|---|
GetTokenAsync(OAuthTokenRequest) | Get a token via client credentials |
GetTokenAsync(OAuthRopcTokenRequest) | Get a token via ROPC flow |
GetTokenAsync(OAuthAuthCodeTokenRequest) | Exchange an authorization code for a token |
GetTokenAsync(OAuthPkceTokenRequest) | Exchange a PKCE code for a token |
GetTokenAsync(OAuthRefreshTokenRequest) | Refresh an expired token |
AuthorizeUrlAsync(clientId, redirectUri, ...) | Generate an authorization URL |
GetTokenAsync overloads also accept *WithScopes request variants (e.g. OAuthTokenRequestWithScopes) to request scoped tokens.
For detailed usage and end-to-end examples, see the Authentication Guide. For standalone use without
CortiClient, see CustomAuthClient below.CustomAuthClient
A standalone authentication client for when you need OAuth token management without the fullCortiClient. Useful for proxy servers, custom backends, or applications that handle tokens separately from API calls.
C# .NET
using Corti;
// Replace these with your values
const string CLIENT_ID = "<your-client-id>";
const string CLIENT_SECRET = "<your-client-secret>";
const string ENVIRONMENT = "<eu-or-us>";
const string TENANT = "<your-tenant-name>";
var auth = CustomAuthClient.Create(
new CortiAuthClientOptions
{
TenantName = TENANT,
Environment = ENVIRONMENT,
});
var tokenResponse = await auth.GetTokenAsync(
new OAuthTokenRequest
{
ClientId = CLIENT_ID,
ClientSecret = CLIENT_SECRET,
});
Console.WriteLine(tokenResponse.AccessToken);
Constructor options
| Property | Type | Required | Description |
|---|---|---|---|
TenantName | string | Yes | Your Corti tenant name |
Environment | string | CortiClientEnvironment | Yes | API region or custom environment |
RequestOptions | CortiRequestOptions? | No | Default request options |
Methods
| Method | Description | Returns |
|---|---|---|
GetTokenAsync(OAuthTokenRequest) | Get a token via client credentials | AuthTokenResponse |
GetTokenAsync(OAuthRopcTokenRequest) | Get a token via ROPC flow | AuthTokenResponse |
GetTokenAsync(OAuthAuthCodeTokenRequest) | Exchange an authorization code for a token | AuthTokenResponse |
GetTokenAsync(OAuthPkceTokenRequest) | Exchange a PKCE code for a token | AuthTokenResponse |
GetTokenAsync(OAuthRefreshTokenRequest) | Refresh an expired token | AuthTokenResponse |
AuthorizeUrlAsync(clientId, redirectUri, codeChallenge?, scopes?) | Generate an authorization URL | string |
GetTokenAsync overloads also accept *WithScopes request variants to request scoped tokens.
For end-to-end examples of each method, see the Authentication Guide.
Authentication types
TheCortiClientAuth abstract record has the following concrete variants used with the CortiClient constructor:
| Variant | Parameters | Description |
|---|---|---|
CortiClientAuth.ClientCredentials | clientId, clientSecret | Server-to-server (guide) |
CortiClientAuth.AuthorizationCode | clientId, clientSecret, code, redirectUri | Interactive login (guide) |
CortiClientAuth.Pkce | clientId, code, redirectUri, codeVerifier | Public client login (guide) |
CortiClientAuth.Ropc | clientId, username, password | Username/password (guide) |
CortiClientAuth.Bearer | accessToken, clientId?, refreshToken?, expiresIn?, refreshExpiresIn?, refreshAccessToken? | Existing token (guide) |
CortiClientAuth.BearerCustomRefresh | refreshAccessToken, accessToken?, expiresIn?, refreshToken?, refreshExpiresIn? | Custom refresh logic (guide) |
Error handling
The SDK throws typed exceptions you can catch and inspect:C# .NET
using Corti;
try
{
await client.Interactions.GetAsync("non-existent-id");
}
catch (CortiClientApiException ex)
{
Console.WriteLine($"Status: {ex.StatusCode}");
Console.WriteLine($"Message: {ex.Message}");
Console.WriteLine($"Body: {ex.Body}");
}
| Exception | Status code | When it’s thrown |
|---|---|---|
BadRequestError | 400 | Malformed request |
UnauthorizedError | 401 | Missing or invalid authentication |
ForbiddenError | 403 | Insufficient permissions |
NotFoundError | 404 | Resource not found |
ConflictError | 409 | Resource conflict (e.g. deleting a template with active dependents) |
UnprocessableEntityError | 422 | Validation failed |
InternalServerError | 500 | Server error |
BadGatewayError | 502 | Gateway error |
GatewayTimeoutError | 504 | Gateway timeout |
CortiClientApiException, which inherits from CortiClientException.
Utilities
Helper types for dictation transcript assembly when building a UI on/transcribe:
| Export | Description |
|---|---|
DictationTranscript.Apply(previous, message) | Apply a transcribe transcript packet to a prior snapshot; returns updated committed and interim text |
Environments
UseCortiEnvironments to create custom environments:
C# .NET
using Corti;
// Built-in region
// var env = CortiEnvironments.FromRegion("eu");
// Custom proxy base URL
var env = CortiEnvironments.FromBaseUrl("https://your-proxy.com/api");
var client = new CortiClient(environment: env);
| Method | Description |
|---|---|
FromRegion(region) | Create an environment from a region string |
FromBaseUrl(baseUrl) | Create an environment pointing at a custom proxy URL |