Skip to main content
Follow these steps to get access and start building:
1

Create an account in the Corti Console

The Corti Console is where you can create an account to access Corti AIΒ Β  Create an account
Β Β  Create a project
Β Β  Create API clients
Β Β  Use the client ID and client secret in your app
Β Β  Develop against the API and collaborate with your project team
Β Β  Monitor usage, manage billing and more

2

Authenticate and test the API

Authentication to the API on all environments is governed by OAuth 2.0. This authentication protocol offers enhanced security measures, ensuring that access to patient data and medical documentation is securely managed and compliant with healthcare regulations.
By default, you will receive a client-id and client-secret to authenticate via client credentials grant type.
1

Request an access token

To acquire an access token, request a token from Corti Auth using your client_id and client_secret.
curl \
  "https://auth.$environment.corti.app/realms/base/protocol/openid-connect/token" \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'client_id=xxx' -d 'client_secret=xxx' \
  -d 'grant_type=client_credentials' -d 'scope=openid'
Create your account and client credentials in the Corti Console - in addition to client ID and client secret you’ll see the tenant name and environment.
2

Receive an access token

It will return you an access_token:
Response
{
  "access_token": "eyJhbGciOi...",
  "expires_in": 300,
  "token_type": "Bearer",
  "scope": "profile openid email"
}
As you can see, the access token expires after 300 seconds (5 minutes). By default as per oAuth standards, no refresh token is used in this flow. There are many available modules to manage monitoring expiry and acquiring a new access token. However, a refresh token can be enabled if needed.
Example authentication code snippets for the Corti API in Python, JavaScript, and .NET.

With SDK

Install SDK to your project:
npm install @corti/sdk
# or
yarn add @corti/sdk
# or
pnpm add @corti/sdk
Create a client to call API:
import { CortiClient } from "@corti/sdk";

const client = new CortiClient({
    environment: "YOUR_ENVIRONMENT_ID",
    tenantName: "YOUR_TENANT_NAME",
    auth: {
        clientId: "YOUR_CLIENT_ID",
        clientSecret: "YOUR_CLIENT_SECRET",
    },
});
If you only need a token:
import { CortiAuth } from "@corti/sdk";

const auth = new CortiAuth({
  environment: "YOUR_ENVIRONMENT_ID",
  tenantName: "YOUR_TENANT_NAME",
});

const token = await auth.getToken({
  clientId: "YOUR_CLIENT_ID",
  clientSecret: "YOUR_CLIENT_SECRET",
});

console.log("accessToken:", token.accessToken);

Without SDK

// Replace these with your values
const CLIENT_ID = "<your client id>";
const CLIENT_SECRET = "<your client secret>";
const ENV = "<eu-or-us>";       // "eu" or "us"
const TENANT = "<your tenant>"; // for example "base"

async function getAccessToken() {
  const tokenUrl = `https://auth.${ENV}.corti.app/realms/${TENANT}/protocol/openid-connect/token`;

  const params = new URLSearchParams();
  params.append("client_id", CLIENT_ID);
  params.append("client_secret", CLIENT_SECRET);
  params.append("grant_type", "client_credentials");
  params.append("scope", "openid");

  const res = await fetch(tokenUrl, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: params
  });

  if (!res.ok) {
    throw new Error(`Failed to get token, status ${res.status}`);
  }

  const data = await res.json();
  return data.access_token;
}

// Example usage
getAccessToken().then(token => {
  console.log("Access token:", token);
}).catch(err => {
  console.error("Error:", err);
});

Once you’re authenticated, make requests against the API. Below is a basic example for creating an Interaction. See all API requests and specifications here.

With SDK

REST API:
// Token acquisition and refresh happen automatically
const interactions = await client.interactions.list();
WebSockets:
const streamSocket = await cortiClient.stream.connect({
  id: "<interactionId>"
});

Without SDK

1

Call the base URL

Subsequently you use the access_token to authenticate any API request. The baseURL is dependent on the environment:
baseURL API
api.$environment.corti.app/v2
Create your account and client credentials in the Corti Console - in addition to client ID and client secret you’ll see the tenant name and environment.

If, for example, you are on the eu environment and want to create an interaction as the starting point for any other workflow operations your URL will look like this:
URL to create an interaction
POST https://api.eu.corti.app/v2/interactions/
2

Pass the auth token

For REST API requests, your access_token should be passed as part of the Request Header. Additionally you need to include the Tenant-Name parameter:
API call request header
Tenant-Name: <tenantname>
Authorization: Bearer <access_token>
Create your account and client credentials in the Corti Console - in addition to client ID and client secret you’ll see the tenant name and environment.

For WebSocket connections, the access_token should be passed in as URL parameter. The Tenant-Name is already part of the WebSocket url returned with the create interaction request:
wss url with access_token appended
wss://{streams-url}&token=Bearer {access_token}
Find the full specification for create interaction request in the API Reference

3

Build the API into your application

import { createReadStream } from "node:fs";
import { randomUUID } from "node:crypto";
import { CortiClient } from "@corti/sdk";

const client = new CortiClient({
  environment: "YOUR_ENVIRONMENT_ID",
  tenantName: "YOUR_TENANT_NAME",
  auth: {
    clientId: "YOUR_CLIENT_ID",
    clientSecret: "YOUR_CLIENT_SECRET",
  },
});

const audioPath = "sample.mp3";

const now = new Date();

const { interactionId } = await client.interactions.create({
  assignedUserId: randomUUID(),
  encounter: {
    identifier: randomUUID(),
    status: "planned",
    type: "first_consultation",
    period: {
      startedAt: now,
      endedAt: now,
    },
    title: "Consultation",
  },
});

if (!interactionId) throw new Error("Missing interactionId");

const streamSocket = await client.stream.connect({
  id: interactionId,
  configuration: {
    transcription: {
      primaryLanguage: "en",
      isDiarization: false,
      isMultichannel: false,
      participants: [{ channel: 0, role: "multiple" }],
    },
    mode: { type: "facts", outputLocale: "en" },
  },
});

streamSocket.on("message", (message) => {
  if (message.type === "facts") {
    console.log("Facts:", message);
  } else if (message.type === "transcript") {
    console.log("Transcript:", message);
  } else if (message.type === "error") {
    console.error("Error:", message);
  } else if (message.type === "ENDED") {
    console.log("ENDED");
  }
});

const audioStream = createReadStream(audioPath, { highWaterMark: 32000 });

for await (const chunk of audioStream) {
  streamSocket.sendAudio(chunk);
}

streamSocket.sendEnd({ type: "end" });
For support or questions, please reach out via help.corti.app.
To get access to Corti API click here to sign up