TypeScript SDK

Responses API

Stateful multi-turn conversations with reasoning models, 9 streaming event types, and server-side persistence.

The Responses API (POST /v1/responses) provides a stateful, multi-turn conversation API following the OpenAI Responses schema. It supports reasoning models, tool calling, multi-turn context via previous_response_id, and server-sent event streaming with 9 distinct event types.

Access via client.responses or client.chat.responses.

Non-streaming

Returns a complete ResponsesResponse once the model finishes generating.

Non-streaming

Basic
import Skytells from 'skytells';

const client = Skytells(process.env.SKYTELLS_API_KEY);

const response = await client.responses.create({
model: 'gpt-5.3-codex',
input: [{ role: 'user', content: 'Explain recursion simply.' }],
instructions: 'You are a helpful tutor.',
});

// Output is an array of output messages
console.log(response.output[0].content[0].text);
console.log(response.usage);
// { input_tokens: 32, output_tokens: 120, total_tokens: 152 }

Streaming

Pass stream: true — the method returns AsyncIterable<ResponsesStreamEvent> directly (no extra await).

Streaming

Basic
for await (const event of client.responses.create({
model: 'gpt-5.3-codex',
input: [{ role: 'user', content: 'Write a limerick about JavaScript.' }],
stream: true,
})) {
if (event.type === 'response.output_text.delta') {
  process.stdout.write(event.delta);
}
if (event.type === 'response.completed') {
  console.log('\nDone. Usage:', event.response.usage);
}
}

Parameters

FieldTypeDescription
modelstringModel identifier, e.g. "gpt-5.3-codex"
inputstring | ResponsesInputMessage[]Text prompt or array of role/content messages
instructionsstring | nullSystem-level instructions
streambooleantrue for SSE streaming
max_output_tokensnumber | nullMaximum tokens in the output
temperaturenumberSampling temperature (0–2)
top_pnumberNucleus sampling probability
toolsChatCompletionTool[]Tool/function definitions
tool_choicestring | object'none' | 'auto' | 'required' | { type: 'function', function: { name } }
parallel_tool_callsbooleanAllow parallel tool calls
reasoning{ effort?, summary? }Reasoning effort and summary verbosity
storebooleanPersist the response server-side (for multi-turn)
previous_response_idstring | nullChain to a prior response for multi-turn
metadataRecord<string, unknown>Arbitrary key/value for labelling
userstring | nullEnd-user identifier
truncationstringTruncation strategy ('auto', 'disabled')
frequency_penaltynumberToken frequency penalty
presence_penaltynumberToken presence penalty
text{ format?, verbosity? }Output text formatting options

Multi-turn with previous_response_id

Instead of sending the full conversation history like the Chat API, you pass the id from the previous response. The server reconstructs context automatically.

Multi-turn

Example
// Turn 1
const turn1 = await client.responses.create({
model: 'gpt-5.3-codex',
input: [{ role: 'user', content: 'My name is Alex. What is a closure in JavaScript?' }],
store: true, // persist for future turns
});

console.log(turn1.id); // "resp_abc123"
console.log(turn1.output[0].content[0].text);

// Turn 2 — no need to repeat history
const turn2 = await client.responses.create({
model: 'gpt-5.3-codex',
input: [{ role: 'user', content: 'Can you give me an example using my name?' }],
previous_response_id: turn1.id,
});

console.log(turn2.output[0].content[0].text);
// Model remembers "Alex" from turn 1

Reasoning Models

Use the reasoning parameter with models that support extended thinking:

const response = await client.responses.create({
  model: 'gpt-5.3-codex',
  input: [{ role: 'user', content: 'Solve: if 2x + 5 = 17, what is x?' }],
  reasoning: {
    effort: 'high',      // 'none' | 'low' | 'medium' | 'high'
    summary: 'detailed',  // 'auto' | 'concise' | 'detailed'
  },
});

Streaming Events

The ResponsesStreamEvent is a discriminated union on type. Nine event types:

typeDescription
response.createdInitial response snapshot (status: 'in_progress')
response.in_progressIntermediate state update
response.completedFinal response with full usage
response.output_item.addedNew output message opened
response.output_item.doneOutput message closed
response.content_part.addedContent part within a message opened
response.content_part.doneContent part closed
response.output_text.deltaIncremental text chunk
response.output_text.doneFinal accumulated text for one content part

Event Shapes

delta
// response.output_text.delta
{
type: 'response.output_text.delta',
sequence_number: 5,
output_index: 0,
content_index: 0,
item_id: 'msg_abc123',
delta: 'The Pythagorean' // incremental text
}

Tool Calling

Define tools the same way as the Chat API. Inspect response.output for function call items.

Tool Calling

Example
const response = await client.responses.create({
model: 'gpt-5.3-codex',
input: [{ role: 'user', content: "What's the weather in Berlin?" }],
tools: [
  {
    type: 'function',
    function: {
      name: 'get_weather',
      description: 'Returns current weather',
      parameters: {
        type: 'object',
        properties: { city: { type: 'string' } },
        required: ['city'],
      },
    },
  },
],
tool_choice: 'auto',
});

// Inspect output for tool call items
const outputItem = response.output[0];
console.log(outputItem);

Content Filtering

The Responses API includes Skytells-specific content_filters on the response:

const response = await client.responses.create({
  model: 'gpt-5.3-codex',
  input: [{ role: 'user', content: userInput }],
});

if (response.content_filters?.some(f => f.blocked)) {
  const blocked = response.content_filters.filter(f => f.blocked);
  console.warn('Content blocked:', blocked.map(f => f.source_type));
}

For full content filtering utilities, see Safety.

Response Shape

idstring
Unique response ID (chainable via previous_response_id).
object'response'
Object type.
created_atnumber
Unix timestamp.
statusstring
completed | in_progress | failed.
modelstring
Model used.
outputResponsesOutputMessage[]
Array of ResponsesOutputMessage output messages.
usageobject
input_tokens, output_tokens, total_tokens, plus details on cached/reasoning tokens.
content_filtersResponsesContentFilter[]
Skytells-specific filter results.
instructionsstring | null
System instructions used.
previous_response_idstring | null
Parent response ID.
reasoningobject
effort, summary settings used.
storeboolean
Whether the response was persisted.
metadataRecord<string, unknown>
User metadata.

For the full TypeScript definitions, see Reference.

// ResponsesResponse shape
{
id: "resp_abc123",
object: "response",
created_at: 1700000000,
status: "completed",
model: "gpt-5.3-codex",
output: [{
  id: "msg_001",
  type: "message",
  role: "assistant",
  content: [{
    type: "output_text",
    text: "Recursion is when a function calls itself..."
  }]
}],
usage: {
  input_tokens: 32,
  output_tokens: 120,
  total_tokens: 152,
  output_tokens_details: { reasoning_tokens: 15 }
}
}

Differences from Chat API

FeatureChatResponses
Multi-turnFull history on every callprevious_response_id reference
StateStatelessPersistent with store: true
Input typemessages arrayinput string or array + instructions
Streaming eventsSingle delta stream9 typed event types
Reasoning controlreasoning.effort and summary
Server-side identityid on response (chainable)

Error Handling

import { SkytellsError } from 'skytells';

try {
  const response = await client.responses.create({ /* ... */ });
} catch (e) {
  if (e instanceof SkytellsError) {
    console.error(e.errorId, e.httpStatus, e.message);
  }
}

For the full error reference, see Errors.

How is this guide?

On this page