Skip to main content

Authorize Client Session

To connect a client (browser or mobile app) to a Layercode voice agent, you must first authorize the session. This is done by calling the Layercode REST API endpoint below from your backend. How the authorization flow works: When using a Layercode frontend SDK (such as @layercode/react-sdk or @layercode/js-sdk), the SDK will automatically make a POST request to the authorizeSessionEndpoint URL that you specify in your frontend code. This authorizeSessionEndpoint should be an endpoint on your own backend (not Layercode’s). Your backend receives this request from the frontend, then securely calls the Layercode REST API (https://api.layercode.com/v1/agents/web/authorize_session) using your LAYERCODE_API_KEY. Your backend then returns the client_session_key to the frontend.
Scheduled change: Monday 1 September at 12:00 UTC — the response body will return conversation_id instead of session_id. Until then, you will continue to receive session_id. Plan your upgrade accordingly.
Your Layercode API key should never be exposed to the frontend. Always call this endpoint from your backend, then return the client_session_key to your frontend.

Endpoint

POST https://api.layercode.com/v1/agents/web/authorize_session

Headers

Authorization
string
required
Bearer token using your LAYERCODE_API_KEY.
Content-Type
string
default:"application/json"
required
Must be application/json.

Request Body

agent_id
string
required
The ID of the Layercode agent the client should connect to.
conversation_id
string
(Optional) The conversation ID to resume an existing conversation. If not provided, a new conversation will be created.

Response

client_session_key
string
required
The key your frontend uses to connect to the Layercode WebSocket API.
conversation_id
string
required
The unique conversation ID.
config
object
Optional configuration for this session used by the frontend SDK. When present, it can include:
transcription.trigger, transcription.automatic, transcription.can_interrupt, and VAD settings such as vad.enabled, vad.gate_audio, vad.buffer_frames, vad.model, vad.positive_speech_threshold, vad.negative_speech_threshold, vad.redemption_frames, vad.min_speech_frames, vad.pre_speech_pad_frames, vad.frame_samples.

Example Request

# Example with only agent_id (creates a new session)
curl -X POST https://api.layercode.com/v1/agents/web/authorize_session \
  -H "Authorization: Bearer $LAYERCODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "ag-123456"}'

# Example with agent_id and conversation_id (resumes an existing conversation)
curl -X POST https://api.layercode.com/v1/agents/web/authorize_session \
  -H "Authorization: Bearer $LAYERCODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "ag-123456", "conversation_id": "lc_conv_abc123..."}'

Example Response

{
  "client_session_key": "lc_sesskey_abc123...",
  "conversation_id": "lc_conv_abc123..."
}

Error Responses

error
string
required
Error message describing the problem.
Possible error cases:
  • 400 – Invalid or missing bearer token, invalid agent ID, missing or invalid conversation ID.
  • 402 – Insufficient balance for the organization.
Example error response:
{
  "error": "insufficient balance"
}

Example: Backend Endpoint (Next.js)

Here’s how you might implement an authorization endpoint in your backend (Next.js example):
Next.js app/api/authorize/route.ts
export const dynamic = "force-dynamic";
import { NextResponse } from "next/server";

export const POST = async (request: Request) => {
  // Here you could do any user authorization checks you need for your app
  const endpoint = "https://api.layercode.com/v1/agents/web/authorize_session";
  const apiKey = process.env.LAYERCODE_API_KEY;
  if (!apiKey) {
    throw new Error("LAYERCODE_API_KEY is not set.");
  }
  const requestBody = await request.json();
  if (!requestBody || !requestBody.agent_id) {
    throw new Error("Missing agent_id in request body.");
  }
  try {
    const response = await fetch(endpoint, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${apiKey}`,
      },
      body: JSON.stringify(requestBody),
    });
    if (!response.ok) {
      const text = await response.text();
      throw new Error(text || response.statusText);
    }
    return NextResponse.json(await response.json());
  } catch (error: any) {
    console.log("Layercode authorize session response error:", error.message);
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
};
For other backend frameworks (Express, FastAPI, etc.), the logic is the same: receive a request from your frontend, call the Layercode authorize_session endpoint with your API key, and return the client_session_key to your frontend.

Agents

List Agents

GET https://api.layercode.com/v1/agents
Authorization
string
required
Bearer token using your LAYERCODE_API_KEY.

Response

Returns all agents.
agents
array
required
Each agent object includes id, name, type, agent_template_id, created_at, updated_at, and assigned_phone_numbers (array of phone number assignments with phone_number, twilio_sid, friendly_name, assigned_at).

Example

curl -H "Authorization: Bearer $LAYERCODE_API_KEY" \
  https://api.layercode.com/v1/agents
{
  "agents": [
    {
      "id": "ag-123456",
      "name": "My Agent ag-123456",
      "type": "voice",
      "agent_template_id": "tmpl_default",
      "created_at": "2024-04-01T12:00:00.000Z",
      "updated_at": "2024-04-08T16:30:16.000Z",
      "assigned_phone_numbers": [
        {
          "phone_number": "+15551234567",
          "twilio_sid": "PNxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
          "friendly_name": "Support Line",
          "assigned_at": "2024-04-02T09:21:00.000Z"
        }
      ]
    }
  ]
}

Create Agent From Template

POST https://api.layercode.com/v1/agents
Authorization
string
required
Bearer token using your LAYERCODE_API_KEY.
Content-Type
string
default:"application/json"
required
Must be application/json.
template_id
string
Optional template ID to initialize the agent configuration. If omitted, the default recommended template is used.

Response

Returns the newly created agent record, including configuration and webhook secret.
id
string
required
Unique identifier for the agent.
name
string
required
Human-friendly name assigned by Layercode.
type
string
required
Agent type (currently voice).
config
object
required
Full pipeline configuration cloned from the template.
webhook_secret
string
required
Secret used to validate incoming webhooks.
agent_template_id
string
required
ID of the template used to create the agent.
curl -X POST https://api.layercode.com/v1/agents \
  -H "Authorization: Bearer $LAYERCODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "template_id": "tmpl_sales" }'

Get Agent Details

GET https://api.layercode.com/v1/agents/{agent_id}
Authorization
string
required
Bearer token using your LAYERCODE_API_KEY.

Response

Returns the agent.
id
string
required
Agent ID.
name
string
required
Agent display name.
config
object
required
Current pipeline configuration.
assigned_phone_numbers
array
Array of phone number assignments for this agent.
curl -H "Authorization: Bearer $LAYERCODE_API_KEY" \
  https://api.layercode.com/v1/agents/ag-123456

Update Agent Configuration

POST https://api.layercode.com/v1/agents/{agent_id}
Authorization
string
required
Bearer token using your LAYERCODE_API_KEY.
Content-Type
string
default:"application/json"
required
Must be application/json.
webhook_url
string
URL for production webhooks. When provided, demo_mode is automatically disabled.

Response

Returns the updated agent record with the new configuration.
curl -X POST https://api.layercode.com/v1/agents/ag-123456 \
  -H "Authorization: Bearer $LAYERCODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "webhook_url": "https://example.com/layercode-webhook"
  }'

Sessions

Get Session Details

GET https://api.layercode.com/v1/agents/{agent_id}/sessions/{session_id}
Authorization
string
required
Bearer token using your LAYERCODE_API_KEY.

Response

Returns JSON with details about the session, transcript, and recording status.
session_id
string
required
Connection ID for the session.
agent_id
string
required
ID of the agent.
started_at
string
ISO timestamp when the connection started.
ended_at
string
ISO timestamp when the connection ended (if ended).
duration_ms
number
Total connection duration in milliseconds.
metadata
object
Custom metadata associated with the session.
from_phone_number
string
Caller phone number (Twilio), if applicable.
from_phone_country
string
Caller country code (Twilio), if applicable.
to_phone_number
string
Agent phone number (Twilio), if applicable.
to_phone_country
string
Agent phone number country code (Twilio), if applicable.
ip_address
string
IP address of the connection.
country_code
string
Country code derived from IP address when available.
transcription_duration_seconds
number
Total seconds of user speech.
tts_duration_seconds
number
Total seconds of generated speech.
latency_ms
number
Processing latency in milliseconds.
transcript
array
Array of transcript entries. Each entry includes: timestamp, user_message, assistant_message, latency_ms.
recording_status
string
One of not_available, in_progress, completed.
recording_url
string
If recording_status is completed, a URL to download the WAV recording for this session connection.

Example

curl -H "Authorization: Bearer $LAYERCODE_API_KEY" \
  https://api.layercode.com/v1/agents/ag-123456/sessions/lc_conn_abc123

Download Session Recording

GET https://api.layercode.com/v1/agents/{agent_id}/sessions/{session_id}/recording
Authorization
string
required
Bearer token using your LAYERCODE_API_KEY.
Returns a WAV audio file if available.
curl -L -H "Authorization: Bearer $LAYERCODE_API_KEY" \
  -o session.wav \
  https://api.layercode.com/v1/agents/ag-123456/sessions/lc_conn_abc123/recording
Recordings are generated after a session completes. If a recording is still processing, the details endpoint will return recording_status: “in_progress”.
Once your frontend receives the client_session_key, it can connect to the Layercode WebSocket API to start streaming audio.

Calls

Initiate Outbound Call

POST https://api.layercode.com/v1/agents/ag-123456/calls/initiate_outbound
from_phone_number
string
required
The phone number assigned to your Layercode Agent that will make the call.
Remember: the from_phone_number must be a number already assigned to your Laycode Agent in the dashboard.
to_phone_number
string
required
The phone number to call (e.g., your mobile number for testing).

Response

conversation_id
string
required
The unique conversation ID.
A Session (associated with the returned conversation_id) will be created shortly after once Twilio initiates the call)

Example Request

  curl -X POST https://api.layercode.com/v1/agents/ag-123456/calls/initiate_outbound \
  -H 'Authorization: Bearer $LAYERCODE_API_KEY' \
  -H 'Content-Type: application/json' \
  -D '{
      "from_phone_number": "NUMBER_ASSIGNED_TO_YOUR_AGENT",
      "to_phone_number": "PHONE_NUMBER_TO_CALL"
  }'

Example Response

{
  "conversation_id": "lc_conv_abc123..."
}

Error Responses

error
string
required
Error message describing the problem.
Possible error cases:
  • 400 – Invalid or missing bearer token, missing or request body, invalid from_phone_number (i.e. not assigned to the agent specified in the url).
  • 429 – Account session concurrency limit reached.
  • 402 – Insufficient balance for the organization.

Twilio Voice

TwiML Webhook

Use this endpoint as the Voice webhook in your Twilio phone number configuration. Layercode validates the incoming request, authorizes a session, and returns TwiML that connects the call to your agent’s WebSocket stream.
POST https://api.layercode.com/v1/agents/twilio/twiml
X-Twilio-Signature
string
Signature supplied by Twilio for request verification. Required when you have stored Twilio credentials in Layercode.
Direction
string
required
Call direction reported by Twilio (e.g., inbound or outbound-api).
From
string
required
Caller phone number.
FromCountry
string
Caller country code supplied by Twilio.
To
string
required
Phone number assigned to your agent.
ToCountry
string
Destination country code supplied by Twilio.

Response

Returns TwiML that streams the call to the Layercode Twilio WebSocket endpoint.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Connect>
    <Stream url="wss://twilio.layercode.com/v1/agents/twilio/websocket/{client_session_key}" />
  </Connect>
</Response>
The response Streaming URL is generated dynamically for each request. Do not cache or reuse the client session key.
I