createRealtimeClientSecret method
Future<CreateRealtimeClientSecretResponse>
createRealtimeClientSecret({
- int? expiresAfterSeconds,
- String expiresAfterAnchor = 'created_at',
- Map<
String, dynamic> ? sessionJson, - String sessionType = 'realtime',
- String? model,
- List<
Modality> ? outputModalities, - AudioFormat? inputAudioFormat,
- AudioFormat? outputAudioFormat,
- SpeechVoice? voice,
- num? speed,
- String? instructions,
- dynamic maxOutputTokens,
- List<
RealtimeFunctionTool> ? tools, - ToolChoice? toolChoice,
- Tracing? tracing,
- TurnDetection? turnDetection,
- NoiseReduction? inputAudioNoiseReduction,
- InputAudioTranscription? inputAudioTranscription,
- List<
String> ? include,
Create an ephemeral client secret (ek_...) with an associated session config.
POST /v1/realtime/client_secrets
You can either:
- pass a fully-formed
sessionJson
that matches the docs; or - use the convenience arguments to build a typical minimal config.
Notes:
expiresAfterSeconds
must be 10–7200 (defaults to 600s server-side).session
must contain atype
: "realtime" or "transcription".
Implementation
Future<CreateRealtimeClientSecretResponse> createRealtimeClientSecret({
// Expiration policy
int? expiresAfterSeconds, // 10..7200 (2h). Server default: 600 (10min)
String expiresAfterAnchor = 'created_at',
// Provide a fully-formed session payload if you need full control.
Map<String, dynamic>? sessionJson,
// --- Convenience fields to build a minimal session quickly ---
// (Used only when `sessionJson` is null)
String sessionType = 'realtime', // "realtime" | "transcription"
String? model, // e.g. RealtimeModel.gptRealtime.toJson()
List<Modality>? outputModalities, // e.g. [Modality.audio] or [Modality.text]
// Audio convenience
AudioFormat? inputAudioFormat,
AudioFormat? outputAudioFormat,
SpeechVoice? voice,
num? speed,
// Guidance & tools
String? instructions,
dynamic maxOutputTokens, // int | "inf"
List<RealtimeFunctionTool>? tools,
ToolChoice? toolChoice,
Tracing? tracing,
// Detection/transcription knobs
TurnDetection? turnDetection,
NoiseReduction? inputAudioNoiseReduction,
InputAudioTranscription? inputAudioTranscription, // for transcription sessions
List<String>? include, // e.g. ["item.input_audio_transcription.logprobs"]
}) async {
if (expiresAfterSeconds != null && (expiresAfterSeconds < 10 || expiresAfterSeconds > 7200)) {
throw ArgumentError('expiresAfterSeconds must be between 10 and 7200 seconds.');
}
// Build payload
final payload = <String, dynamic>{};
if (expiresAfterSeconds != null || expiresAfterAnchor != 'created_at') {
payload['expires_after'] = {
'anchor': expiresAfterAnchor,
if (expiresAfterSeconds != null) 'seconds': expiresAfterSeconds,
};
}
// Assemble `session` block
Map<String, dynamic> session = sessionJson ?? {};
if (session.isEmpty) {
// Minimal session using convenience params
session = {'type': sessionType};
if (model != null) session['model'] = model;
if (instructions != null) session['instructions'] = instructions;
if (maxOutputTokens != null) session['max_output_tokens'] = maxOutputTokens;
if (tools != null) session['tools'] = tools.map((t) => t.toJson()).toList();
if (toolChoice != null) session['tool_choice'] = toolChoice.toJson();
if (tracing != null) session['tracing'] = tracing.toJson();
if (turnDetection != null) session['turn_detection'] = turnDetection.toJson();
// Modalities: For realtime sessions, server defaults to ["audio"].
// You may set ["text"] to disable audio output (cannot request both).
if (outputModalities != null && sessionType == 'realtime') {
session['output_modalities'] = outputModalities.map((m) => m.toJson()).toList();
}
// Audio block
final audio = <String, dynamic>{};
// Input sub-block (both session types)
final input = <String, dynamic>{};
if (inputAudioFormat != null) input['format'] = inputAudioFormat.toJson();
if (inputAudioNoiseReduction != null) {
input['noise_reduction'] = inputAudioNoiseReduction.toJson();
}
if (input.isNotEmpty) audio['input'] = input;
if (sessionType == 'realtime') {
// Output sub-block only exists on realtime sessions
final output = <String, dynamic>{};
if (outputAudioFormat != null) output['format'] = outputAudioFormat.toJson();
if (voice != null) output['voice'] = voice.toJson();
if (speed != null) output['speed'] = speed;
if (output.isNotEmpty) audio['output'] = output;
} else {
// Transcription-only session extras
if (include != null) session['include'] = include;
if (inputAudioTranscription != null) {
audio['transcription'] = inputAudioTranscription.toJson();
}
}
if (audio.isNotEmpty) session['audio'] = audio;
}
payload['session'] = session;
final res = await postJson('/realtime/client_secrets', payload);
// The reference returns 201 Created (but accept 200 just in case).
if (res.statusCode == 201 || res.statusCode == 200) {
return CreateRealtimeClientSecretResponse.fromJson(jsonDecode(res.body));
}
throw OpenAIRequestException.fromHttpResponse(res);
}