Skip to main content

openai_dart 12.0.0 copy "openai_dart: ^12.0.0" to clipboard
openai_dart: ^12.0.0 copied to clipboard

Dart client for the OpenAI REST APIs and realtime WebSocket/WebRTC workflows with type-safe access to GPT, image, audio, and Responses APIs.

OpenAI Dart Client #

tests openai_dart Discord MIT

Dart and Flutter client for the OpenAI API. Generate text with the Responses API, stream output, call tools, and work with images, audio, and embeddings.

Tip

Coding agents: start with llms.txt for documentation and examples.

Table of Contents

Features #

  • Responses API: text generation, streaming, conversations, structured output, vision, and tool calling.
  • Chat Completions, Decisions, embeddings, and image and audio generation.
  • Built-in web search, file search, Code Interpreter, computer use, and custom tools.
  • Files, batches, fine-tuning, signed webhooks, and safety resources.
  • Realtime and Live sessions, persistent Responses WebSockets, Agents, and Vaults.
  • Pure Dart support for Dart and Flutter on mobile, desktop, web, and servers.

Why choose this client? #

  • Use typed Dart requests and responses with a resource API similar to the official SDKs.
  • Use the same client in Dart backends and Flutter apps, without a Flutter dependency.
  • Get streaming helpers, configurable retries, interceptors, and typed exceptions.
  • Rely on strict semver and migration guides when upgrading.

Quickstart #

Requires Dart 3.12 or later and works with Dart and Flutter. Set OPENAI_API_KEY in your environment before running this native Dart example. For upgrades, see the Migration Guide.

dependencies:
  openai_dart: ^12.0.0
import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final response = await client.responses.create(
      const CreateResponseRequest(
        model: 'gpt-5.5',
        input: ResponseInput.text('What is the capital of France?'),
      ),
    );
    print(response.outputText);
  } finally {
    client.close();
  }
}

Keep API keys on trusted infrastructure. For a distributed Flutter or web app, route requests through your backend.

Configuration #

API keys, environment variables, and client lifetime

OpenAIClient.fromEnvironment() reads OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_ORG_ID, and OPENAI_PROJECT_ID. It also reads optional OPENAI_WEBHOOK_SECRET for local verification. Environment loading is for native Dart; use explicit configuration when environment variables are unavailable.

OpenAIClient.withApiKey('YOUR_API_KEY') creates a client from a supplied key. Reuse a client for multiple requests and call close() when finished; an injected HTTP client remains caller-owned.

Timeouts, retries, and custom endpoints

Use OpenAIConfig for a proxy, timeout, retry policy, or organization/project selection.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient(
    config: OpenAIConfig(
      authProvider: ApiKeyProvider('YOUR_API_KEY'),
      baseUrl: 'https://api.openai.com/v1',
      timeout: const Duration(minutes: 10),
      connectTimeout: const Duration(seconds: 30),
      retryPolicy: const RetryPolicy(maxRetries: 3),
      // organization: 'org-...',
      // project: 'proj-...',
    ),
  );

  try {
    final response = await client.responses.create(
      const CreateResponseRequest(
        model: 'gpt-5.5',
        input: ResponseInput.text('Hello!'),
      ),
    );
    print(response.outputText);
  } finally {
    client.close();
  }
}

For Azure, set the deployment URL and use AzureApiKeyProvider. See Error Handling for retry boundaries.

Update configuration and rotate credentials

Use client.updateConfig(...) or client.updateAuthProvider(...), then acquire a fresh resource handle. Previously obtained handles keep their original configuration, including child resources, retries, streams, and WebSocket recovery. An update shares the existing HTTP pool and leaves active work running.

client.updateConfig(
  authProvider: ApiKeyProvider('NEW_API_KEY'),
  timeout: const Duration(seconds: 60),
  organization: null, // Explicit null clears this optional setting.
);
final responses = client.responses; // Uses the updated settings.

Omitted options retain their values; defaultHeaders: {} clears global headers. Header maps are copied. For credential rotation used by retained handles, supply an AuthProvider that returns a fresh map for each request. Providers and custom interceptors keep their application-owned state. Logging body policy follows the handle; the package logger's filtering level remains shared.

→ Offline runtime configuration example

Imports for Realtime and retained Assistants types

The main import is package:openai_dart/openai_dart.dart. Realtime uses package:openai_dart/openai_dart_realtime.dart. Retained Assistants types use package:openai_dart/openai_dart_assistants.dart; that API shut down on August 26, 2026. See the Responses migration guide.

How do I use Responses through Google Vertex?

Inject a Google token callback; your application owns credential refresh/caching. The provider acquires a token for each HTTP attempt, including retries.

final provider = VertexProvider(
  project: 'my-google-project',
  location: 'global',
  tokenProvider: () async => googleCredentials.accessToken(),
);
final client = OpenAIClient(config: OpenAIConfig.vertex(provider: provider));

Use the regular client.responses create, retrieve, cancel, delete, input-items and compact methods, plus createStream for SSE. A complete baseUrl on VertexProvider can replace project/location for a trusted proxy. Other resources, Responses listing/token counting and WebSockets are unsupported and fail locally. Do not supply OpenAI auth, organization/project or custom auth headers.

The request timeout includes token acquisition and response headers; buffered HTTP also retains its normal body timeout. SSE has no whole-stream deadline: use an abort trigger or cancel its subscription. Late timed-out/aborted token results cannot dispatch a request; the application still owns cancellation of any work inside its callback. Redirect following is disabled. Closing the client promptly aborts provider work, including unresolved token waits, while callback-owned work remains application-owned. Borrowed HTTP pools remain caller-owned; a dedicated stream factory retains its normal close-on-completion policy. Provider updates use updateConfig(vertexProvider: replacement) and the same retained-resource snapshot rules described above.

The portable callback path uses no Google dependency or automatic ADC discovery. VertexProvider.fromEnvironment reads Google project/location on native Dart and still requires an injected callback. Browser/Wasm use explicit routing; endpoint CORS, access permissions and model availability remain service-controlled.

→ Runnable offline Vertex example

How do I select an OpenAI regional endpoint?
final client = OpenAIClient(
  config: OpenAIConfig.forDataResidency(
    OpenAIDataResidency.eu,
    authProvider: ApiKeyProvider(euProjectApiKey),
  ),
);

The named SDK mapping supports global, us, eu and ae. US/EU support eligible regional processing; UAE processing is limited to supported model/service combinations. The official guide also lists storage-only regional endpoints (Australia, Canada, Japan, India, Singapore, South Korea and the UK); select their complete root through ordinary OpenAIConfig(baseUrl: ...) when applicable. Regional storage does not imply regional processing. A matching project, approved account settings and eligible models/features are still required; endpoint or credential selection alone provides no residency guarantee. Google Vertex locations are a separate provider setting.

→ Official data controls and regional support

Usage #

Start with the Responses API for a model call and its output. Expand a topic for a short example or a link to a complete workflow.

Responses API #

How do I create a response?

Call client.responses.create with a model and input. Read the generated text with response.outputText and token usage with response.usage.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final response = await client.responses.create(
      const CreateResponseRequest(
        model: 'gpt-5.5',
        input: ResponseInput.text('What is the capital of France?'),
      ),
    );
    print(response.outputText);
  } finally {
    client.close();
  }
}

→ Full example

How do I stream responses?

Use client.responses.createStream and textDeltas() to display text as it arrives. Use the typed events or accumulate() when you also need tool calls and response metadata; collectText() consumes the stream into one string.

import 'dart:io';

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final stream = client.responses.createStream(
      const CreateResponseRequest(
        model: 'gpt-5.5',
        input: ResponseInput.text('Tell me a short story.'),
      ),
    );
    await for (final text in stream.textDeltas()) {
      stdout.write(text);
    }
  } finally {
    client.close();
  }
}

→ Full example

How do I continue a conversation?

Pass the previous response ID with the next input. For separately managed conversation history, use client.conversations.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final first = await client.responses.create(
      const CreateResponseRequest(
        model: 'gpt-5.5',
        input: ResponseInput.text('My name is Alice.'),
      ),
    );
    final next = await client.responses.create(
      CreateResponseRequest(
        model: 'gpt-5.5',
        previousResponseId: first.id,
        input: const ResponseInput.text('What is my name?'),
      ),
    );
    print(next.outputText);
  } finally {
    client.close();
  }
}

→ Full example · Conversations example

How do I get structured JSON output?

Set TextConfig.format to JsonSchemaFormat to request output matching your schema. Check for refusals and incomplete responses before decoding the text.

import 'dart:convert';

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final response = await client.responses.create(
      const CreateResponseRequest(
        model: 'gpt-5.5',
        input: ResponseInput.text('Extract the name from: Alice is a doctor.'),
        text: TextConfig(
          format: JsonSchemaFormat(
            name: 'person',
            strict: true,
            schema: {
              'type': 'object',
              'properties': {
                'name': {'type': 'string'},
              },
              'required': ['name'],
              'additionalProperties': false,
            },
          ),
        ),
      ),
    );
    if (response.status == ResponseStatus.completed &&
        response.outputText.isNotEmpty) {
      print(jsonDecode(response.outputText));
    }
  } finally {
    client.close();
  }
}

→ Responses example

How do I use tool calling?

Define a function with JSON Schema parameters. Your application executes the requested function and returns its result with the original callId; the client does not execute tools for you.

import 'dart:convert';

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final response = await client.responses.create(
      CreateResponseRequest(
        model: 'gpt-5.5',
        input: const ResponseInput.text(
          'Use the add tool to calculate 123 + 456.',
        ),
        tools: [
          ResponseTool.function(
            name: 'add',
            description: 'Add two numbers',
            parameters: {
              'type': 'object',
              'properties': {
                'a': {'type': 'number'},
                'b': {'type': 'number'},
              },
              'required': ['a', 'b'],
              'additionalProperties': false,
            },
          ),
        ],
      ),
    );
    final results = <Item>[];
    for (final call in response.functionCalls) {
      if (call.name != 'add') throw StateError('Unknown tool: ${call.name}');
      final args = jsonDecode(call.arguments) as Map<String, dynamic>;
      final sum = (args['a'] as num) + (args['b'] as num);
      results.add(
        FunctionCallOutputItem.string(
          callId: call.callId,
          output: sum.toString(),
        ),
      );
    }
    if (results.isNotEmpty) {
      final finalResponse = await client.responses.create(
        CreateResponseRequest(
          model: 'gpt-5.5',
          previousResponseId: response.id,
          input: ResponseInput.items(results),
        ),
      );
      print(finalResponse.outputText);
    } else {
      print(response.outputText);
    }
  } finally {
    client.close();
  }
}

→ Responses example · Async tool results

How do I analyze images?

Include text and image content in a Responses input message. Images can be supplied as a public URL, a data URL, or an uploaded file ID.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final response = await client.responses.create(
      const CreateResponseRequest(
        model: 'gpt-5.5',
        input: ResponseInput.items([
          MessageItem(
            role: MessageRole.user,
            content: [
              InputContent.text('What is in this image?'),
              InputContent.imageUrl('https://example.com/image.jpg'),
            ],
          ),
        ]),
      ),
    );
    print(response.outputText);
  } finally {
    client.close();
  }
}

→ Full example · Chat vision example

How do I search the web?

Add ResponseTool.webSearch() to let the model search for current information. The full examples also show location hints, domain filters, sources, and image results.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final response = await client.responses.create(
      CreateResponseRequest(
        model: 'gpt-5.5',
        input: const ResponseInput.text(
          'What are the latest developments in AI?',
        ),
        tools: [ResponseTool.webSearch()],
      ),
    );
    print(response.outputText);
  } finally {
    client.close();
  }
}

→ Full example · Search controls

How do I count input tokens?

Use client.responses.inputTokens.count to estimate input size before generating a response.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final count = await client.responses.inputTokens.count(
      model: 'gpt-5.5',
      input: const ResponseInput.text('Hello, how are you?'),
    );
    print(count.inputTokens);
  } finally {
    client.close();
  }
}

→ Full example

Which model IDs and account settings can I use?

Model IDs are open strings, including gpt-6.1-terra. GPT-6 Rosalind requires trusted access for authorized internal research; an ID does not grant access. See the model catalog and API changelog.

Paid usage tiers Build, Launch, and Grow, project service-tier permissions, and subscription API credits are managed by OpenAI. They are separate from a request's serviceTier. Review rate limits and credit eligibility; the client does not change account entitlements.

→ Responses model-call example

Other model APIs #

How do I use chat completions?

Use client.chat.completions.create for applications built around Chat messages. Read the first choice with response.text; new applications can start with the Responses examples above.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final response = await client.chat.completions.create(
      ChatCompletionCreateRequest(
        model: 'gpt-5.5',
        messages: [
          ChatMessage.system('You are a helpful assistant.'),
          ChatMessage.user('What is the capital of France?'),
        ],
      ),
    );
    print(response.text);
  } finally {
    client.close();
  }
}

→ Full example

How do I stream chat completions?

Use client.chat.completions.createStream with textDeltas() or ChatStreamAccumulator. Set StreamOptions(includeUsage: true) for final usage; the usage-only chunk can have no choices.

→ Full example

How do I classify or score shared input?

Use client.decisions.create for typed predicate, choice, and score questions. Answers can include refusals. Shared input supports text, JSON, images, and conversation/tool history; each request accepts up to 400 questions. Use DecisionInstructions.parts with the *WithInstructions question factories for question-specific text, images, and JSON. Optional cache controls apply to shared input only; Decisions supports a 30m TTL.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final decision = await client.decisions.create(
      DecisionRequest(
        model: 'gpt-6-luna',
        input: DecisionInput.text('The screen arrived broken.'),
        questions: [
          DecisionQuestion.predicate(
            name: 'damaged',
            instructions: 'Does the customer report a damaged item?',
          ),
        ],
      ),
    );
    for (final answer in decision.answers) {
      if (answer case PredicateDecisionAnswer(:final probability)) {
        print('Damage probability: $probability');
      } else if (answer is RefusalDecisionAnswer) {
        print('The question was refused.');
      }
    }
  } finally {
    client.close();
  }
}

→ Full example · GA inputs and caching (offline) · Image input example

How do I create embeddings?

Use client.embeddings.create to generate text vectors. Set dimensions when you need a smaller vector.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final response = await client.embeddings.create(
      EmbeddingRequest(
        model: 'text-embedding-3-small',
        input: EmbeddingInput.text('Hello, world!'),
        dimensions: 256,
      ),
    );
    print(response.firstEmbedding);
  } finally {
    client.close();
  }
}

→ Full example

Images and audio #

How do I generate and edit images with GPT Image 2.5?

Use client.images.generate or edit with an explicit model. Use editJson for URL, data URL, or file-ID inputs; generation and editing also have streaming variants.

import 'dart:convert';
import 'dart:io';

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final response = await client.images.generate(
      const ImageGenerationRequest(
        model: ImageModels.gptImage25Flare,
        prompt: 'A cute robot holding a flower',
        size: ImageSize.size1024x1024,
      ),
    );
    final image = response.data.first.b64Json;
    if (image != null) {
      await File('robot.png').writeAsBytes(base64Decode(image));
    }
  } finally {
    client.close();
  }
}

GPT Image 1 retired on October 23, 2026. Older gpt-image-1.5, gpt-image-1-mini and chatgpt-image-latest retire on December 1; use Sunburst or Flare. See the deprecation schedule.

→ Full example · Model selection

How do I guide an image edit with markup?

Set ImageEditRequest.markup to PNG bytes for multipart uploads, or ImageEditJsonRequest.markup to an ImageReference for JSON edits. The overlay must include transparent pixels and match the first input image's dimensions after orientation. Markup and mask are mutually exclusive; the service validates image contents and model support.

Pass a stable, privacy-preserving safetyIdentifier of at most 128 characters on each image request. A nonempty identifier takes precedence over deprecated user; omission, null, or an empty string leaves that fallback to the service. Ordinary responses and completed image events expose the effective identifier.

Responses image-tool calls retain ImageGenerationCallStatus.failed/.generating and optional error.moderationDetails, including the stage and public categories. Use supported explicit image models; gpt-image-1 shut down October 23, 2026.

→ Offline markup and safety-identifier example

How do I use audio?

Use client.audio.speech.create for speech bytes, createByteStream for audio chunks, and createStream for typed speech events. Transcription and translation are available through client.audio.transcriptions and client.audio.translations.

import 'dart:io';

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final bytes = await client.audio.speech.create(
      const SpeechRequest(
        model: 'gpt-4o-mini-tts',
        input: 'Hello! How are you today?',
        voice: SpeechVoice.marin,
        responseFormat: SpeechResponseFormat.mp3,
      ),
    );
    await File('speech.mp3').writeAsBytes(bytes);
  } finally {
    client.close();
  }
}

→ Full example · Streaming speech · Transcription and translation

How do I generate, replay, and stream Chat audio?

Request Chat audio through client.chat.completions and choose a built-in or custom voice. Replay the returned audio ID in later messages; accumulate streamed audio before decoding it.

→ Full example

How do I manage voice consent recordings?

Use client.audio.voiceConsents to upload and manage consent recordings before creating custom voices.

→ Full example

How do I create a custom voice?

Create a saved voice with PromptVoiceCreateRequest(name: ..., prompt: ...), then select its ID with LiveVoice.custom(id: voice.id) at Live startup. Prompt voices work only in Live. Delete a saved voice explicitly with client.audio.voices.delete(voice.id).

For a recording-based voice, keep using CustomVoiceCreateRequest with a consent ID and audio sample. Prompt requests default to JSON; set encoding: VoiceCreateEncoding.multipart when needed.

→ Prompt create/use/delete example · Consented sample example

Files, batches, and model evaluation #

How do I manage files?

Use client.files to upload, list, retrieve, and delete files. Use client.uploads for large multipart uploads.

import 'dart:io';

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final file = await client.files.upload(
      bytes: await File('training.jsonl').readAsBytes(),
      filename: 'training.jsonl',
      purpose: FilePurpose.fineTune,
    );
    print(file.id);
  } finally {
    client.close();
  }
}

→ Full example · Large uploads

How do I use batch processing?

Use client.batches.create to submit a JSONL input file for asynchronous processing. Retrieve the batch status and output file when it completes.

→ Full example

How do I fine-tune a model?

Create a job through client.fineTuning.jobs with a training file ID, then retrieve its status and resulting model name.

→ Full example

Webhooks and safety #

How do I receive signed webhooks?

Verify the original request bytes and headers with WebhookVerifier.unwrapBytes before reading an event. WebhookVerifier.fromEnvironment() reads OPENAI_WEBHOOK_SECRET without an API key; handle invalid signatures, acknowledge receipt, and deduplicate deliveries in your receiver.

→ Full example

Environment notifications are typed for agent.environment.ready, failed, suspended and expired. Subscribe with the corresponding WebhookEventType.agentEnvironment* choices, verify the original delivery bytes, and retrieve the environment using the typed payload’s id. Ready/failed concern prewarm setup; suspended may resume from a snapshot, while expired cannot. Receivers own acknowledgment and deduplication.

→ Offline environment notification example

How do I manage webhook endpoints?

Use client.webhooks to create, list, update, delete, rotate, and test project endpoints, and client.webhooks.eventTypes.list() to discover webhook event types. Save signing secrets returned by creation or rotation securely; test sends a real delivery.

→ Full example

How do I moderate content?

Use client.moderations.create to check text against content policies.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final result = await client.moderations.create(
      ModerationRequest(input: ModerationInput.text('Check this text')),
    );
    print(result.results.first.flagged);
  } finally {
    client.close();
  }
}

→ Full example

How do I investigate verified safety notifications?

Use client.safety.alerts for project alerts and client.safety.cases for organization cases. Retrieve IDs from verified notices using credentials for the correct scope.

→ Full example · Full example

How do I inspect monitoring failures?

Inspect typed monitoring details on HTTP exceptions, failed Responses, and WebSocket errors. These details describe the failure; they do not automatically resume work or execute suggested actions.

→ Full example

How do I check content provenance?

Use client.contentProvenanceChecks.create to inspect an image or audio file for C2PA and SynthID signals. Dispatch on the returned result type.

→ Full example

Advanced Responses workflows #

How do I use persistent Responses WebSockets?

Use client.responses.connect() for persistent requests. Add an opt-in session to route parallel lanes and collect final responses within explicit local budgets. Browser connections require an authenticated backend proxy because WebSockets cannot send API-key headers.

final connection = await client.responses.connect();
final session = ResponsesWebSocketSession(
  connection,
  limits: const ResponsesWebSocketLimits(
    maxLanes: 4,
    maxEventsPerLane: 1024,
    maxEvents: 2048,
    maxBytesPerLane: 4 * 1024 * 1024,
    maxBytes: 8 * 1024 * 1024,
    maxResponseBytes: 8 * 1024 * 1024,
  ),
);
try {
  final planner = session.lane('planner');
  planner.create(const CreateResponseRequest(
    model: 'gpt-6-sol',
    input: ResponseInput.text('Prepare the planner context.'),
  ), generate: false);
  final warmup = await planner.getFinalResponse();
  planner.create(CreateResponseRequest(
    model: 'gpt-6-sol',
    previousResponseId: warmup.id,
    input: const ResponseInput.text('Draft a short plan.'),
  ));
  final response = await planner.getFinalResponse();
  print(response.outputText);
} finally {
  await session.close(); // Detaches the helper.
  await connection.close();
}

streamId routes a lane; previousResponseId selects conversation history. getFinalResponse() also returns failed/incomplete responses, so inspect status. Use lane.receive() for individual events. Cancel a wait with abortTrigger and resume on the same lane; lane.close() releases its retained state. Detached IDs remain reserved on that connection. Session helpers currently require recovery to be disabled.

To change output format mid-session, include ConfigurationUpdateItem(text: ConfigurationUpdateText(format: JsonSchemaFormat(...))) in the next request's input. Use const ConfigurationUpdateText.plainText() to reset; omitting text leaves it alone. JSON object mode and explicit null updates are unsupported.

→ Offline session example: manual tool continuation, fork barrier, and compacted-history replay. Low-level example retains direct connection use.

How do I steer a running Responses request?

Use the steering controls to submit input during an active response. Respect pending continuation state so accepted input and completed tool results are not sent twice.

→ Full example

How do I recover a Responses WebSocket?

Opt into connection recovery and handle queued or unsent requests explicitly. Recovery reconnects the transport without automatically replaying frames already sent to the server.

→ Full example

How do I use async function and custom tools?

Declare async tools and return results with their original call IDs. Continue from the latest response ID when concurrent jobs complete. Use ResponseToolChoice.custom(name: 'my_tool') to select a declared custom tool.

→ Full example

How do I return client-discovered tools?

Return complete discovered function or custom-tool definitions with the original tool-search call ID. The example shows discovery and continuation without executing the tools.

→ Full example

How do I filter web search and inspect image results?

Configure domain and content-type filters on ResponseTool.webSearch and request sources or image results. Search output is available through both ordinary Responses and streamed events.

→ Full example

How do I replay reasoning across tool calls?

Convert completed reasoning output with ReasoningItem.toInput() and keep it in the original history order. For a reasoning/function-call turn:

final history = <Item>[...previousInput];
for (final item in response.output) {
  history.add(switch (item) {
    final ReasoningItem reasoning => reasoning.toInput(),
    final FunctionCallOutputItemResponse call => call.toFunctionCallItem(),
    _ => throw StateError('Handle this output kind before replaying it.'),
  });
}
// After your application executes the requested tool:
history.add(FunctionCallOutputItem.string(
  callId: callId,
  output: toolResult,
));
final next = await client.responses.create(CreateResponseRequest(
  model: model,
  input: ResponseInput.items(history),
));

ReasoningInputItem also supports direct construction and Item.fromJson(), with required id and summary. It keeps plaintext content, summaries, opaque encrypted state, status and beta agent metadata separate from assistant text. Use finalized streaming items; an added item's encrypted state may be unfinished.

Provider support differs: DeepSeek supports plaintext reasoning input but does not support summaries or encrypted reasoning. Raw ResponseInput.fromOutputItems(...) remains available for provider-specific shapes. This helper preserves returned data; it does not generate or interpret reasoning.

→ Offline example

How do I change reasoning effort during a conversation?

Insert a ConfigurationUpdateItem before the next user input to change subsequent reasoning effort while preserving the request-level baseline. The full example covers replay and the supported compaction boundaries.

→ Full example

How do I prewarm the prompt cache and inspect diagnostics?

Use ResponsePromptCacheOptionsParam for Responses prewarming, TTL, and comparison diagnostics. Chat uses the narrower PromptCacheOptionsParam; returned usage counters report actual cached tokens.

Set PromptCacheBreakpointConfig(ttl: PromptCacheBreakpointTtl.hours12) on stable shared content for a 12-hour boundary. Omit ttl to inherit the request. The pinned top-level PromptCacheTtl still permits only 30m; Decisions uses separate cache controls.

Read response.toolUsage separately from response.usage for hosted image-generation tokens and billable web searches. Missing tool usage or cached counts mean unknown, not zero.

→ Full example · Breakpoint TTLs and tool usage (offline)

How do I configure an execution container?

Use client.containers to create a container with a memory tier and network policy, then pass its ID to Code Interpreter. See the migration guide for v11 configuration changes.

→ Full example

How do I configure hosted shell and return local results?

Configure a hosted shell through Responses tools, or execute local commands in your application and return their outputs. The client does not run local shell commands automatically.

→ Full example

How do I observe compaction progress?

Watch typed compaction events in the Responses stream. Progress events are nonterminal; preserve the complete returned compacted output for continuation.

→ Full example

How do I select and inspect an access program?

Set access-program options explicitly when your account is eligible, and inspect the effective program returned by the service. Selection does not provision access or change account eligibility.

→ Full example

How do I inject multi-agent tool results?

Use beta multi-agent injection to return tool results to the owning agent. Track acknowledgments and uncommitted results explicitly rather than rerunning tools after uncertain delivery.

→ Full example

Live and Realtime #

How do I use the Realtime API?

Import openai_dart_realtime.dart for Realtime WebSocket and WebRTC sessions with audio events. Use client.realtimeSessions for ephemeral client secrets and WebRTC calls; your application owns capture, playback, and peer-connection setup.

import 'dart:io';

import 'package:openai_dart/openai_dart_realtime.dart' as realtime;

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final session = await client.realtime.connect(model: 'gpt-realtime-2.1');
    try {
      session.sendUserMessage('Say hello.', createResponse: false);
      session.createResponse(outputModalities: ['text']);
      await for (final event in session.events) {
        if (event is realtime.ResponseTextDeltaEvent) {
          stdout.write(event.delta);
        } else if (event is realtime.ResponseDoneEvent) {
          break;
        } else if (event is realtime.ErrorEvent) {
          throw StateError(event.error.message);
        }
      }
    } finally {
      await session.close();
    }
  } finally {
    client.close();
  }
}

→ Full example

How do I select Realtime response input and noise strength?

Pass RealtimeResponseInputItem values to connection.createResponse(input: ...) to reference existing items or supply typed message/function-call history. Setting input creates a context for that response; input: [] clears its context. References use existing server item IDs. Set conversation: 'none' to keep the response output out of the default conversation.

Set AudioInputNoiseReduction.strength between 0 and 1. Omit strength on an update to preserve the current value; clearing the wrapper's noise reduction disables filtering. Use RealtimeAudioConfigOutput.voiceSelection for an audio-sample custom voice, or keep voice for a named voice. Prompt-generated custom voices support Live only.

→ Offline response input example

How do I stream Realtime translation?

Use client.realtime.connectTranslation(model: 'gpt-realtime-translate') and consume typed source/output transcript and audio events. Translation runs continuously from raw 24 kHz PCM16 mono input; configure language, source transcription and noise reduction with RealtimeTranslationSessionUpdateRequest. Request closeSession() and keep reading through RealtimeTranslationSessionClosedEvent before local cleanup.

Create scoped credentials with client.realtimeSessions.translations.createClientSecret(...). Native/server WebSockets can use them; browsers use WebRTC or an authenticated backend proxy because browser WebSockets cannot set authentication headers. Your application owns audio capture and playback.

→ Offline translation example

Which audio models need migration?

The announced audio shutdowns require choosing the replacement workflow as well as a model:

Shutdown Existing family or endpoint Replacement
January 6, 2027 tts-1, tts-1-hd, gpt-4o-mini-tts Realtime speech generation with gpt-realtime-2.1-mini
January 20, 2027 Legacy Realtime and audio families gpt-realtime-2.1 / gpt-realtime-2.1-mini, or Chat audio with gpt-audio-1.5
February 26, 2027 Legacy Whisper/transcribe families; /audio/translations gpt-transcribe / gpt-live-transcribe, or Realtime translation

See the official deprecation schedule for affected snapshots and route-specific migration guidance. Realtime beta was already removed on May 12, 2026; its retained codecs are for compatibility, and new sessions use GA. Model identifiers remain open strings.

→ Realtime connection example

How do I recover Live and Realtime WebSockets?

Enable LiveReconnectOptions or RealtimeReconnectOptions explicitly. Both default to rejecting sends during recovery; set maxQueueBytes to retain new, never-attempted frames. After reconnecting, restore application state and call connection.flushPending(), or retrieve frames with connection.takePending().

Live primary and fork connections require a fresh explicit start(...) acknowledgment before pending work can flush. Realtime and Translation configuration, history, and audio are never restored automatically. Finalize only while the session is connected. Attempted writes are never replayed; inspect connection.recovery!.done for the final unsent report.

Browser WebSockets reject custom headers. Use WebRTC or an authenticated backend proxy.

→ Local example, no API charges

How do I signal Live sessions and control calls?

Use client.live for WebRTC/SIP signaling, explicit call controls, and recordings. The full example also handles verified incoming-call notices.

→ Full example

How do I use primary and sideband Live WebSockets?

Connect primary or sideband Live WebSockets to observe typed events and control a session. Your application handles media and tool delegation, and awaits graceful finalization.

→ Full example

How do I connect Live to Decisions?

Configure LiveDecisionsDelegationParam for native delegation, or add input/output transcript triggers with LiveDecisionTriggerInputParam. Live question groups allow up to 64 questions; use LiveDecisionQuestion for their distinct content rules.

Append shared context with LiveDecisionItemCreateParam, evaluate explicitly with a unique LiveDecisionCreateParam.eventId, and read LiveDecisionEvent.typedDecision. Wait for configuration/item acknowledgments before using new state. Trigger results identify their source transcript delta and can arrive out of order; your application decides which result to apply and performs any actions. When filtering WebRTC events, allow decision.event and each configured source transcript event.

→ Offline delegation and transcript-trigger example

How do I play Live audio fixtures and send SIP DTMF?

Send LiveOutputAudioFixturePlayParam.fromBytes(...) with up to 30 seconds of raw mono PCM16 little-endian audio at 24 kHz. Wait for LiveOutputAudioFixturePlaying (accepted), then LiveOutputAudioFixturePlayed (server mixer drained); transport audio may still be buffered. Input is dropped and instruction/thinking/commentary appends are rejected during playback. Independent input mute remains separate.

For SIP calls, send one key with LiveTransportDTMFSendParam(event: '#', eventId: ...) on the server sideband. LiveTransportDTMFSent confirms sending to the SIP trunk; LiveTransportDTMFReceived carries caller keypresses. Match optional client correlation IDs and handle server errors explicitly.

→ Offline audio fixture and DTMF example

How do I fork stored Live sessions and group captions?

Fork a stored Live session and use transcript helpers to group captions. The example covers inherited state and caller-owned channel cleanup.

→ Full example

Agents and Vaults #

How do I save and update an agent configuration?

Use client.agents to save reusable model, instruction, and tool configuration. Creating an agent stores configuration without starting a session; updates preserve omitted fields, while clearX flags reset nullable settings.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    final agent = await client.agents.create(
      CreateAgentRequest(model: 'gpt-5.5', name: 'Research assistant'),
    );
    try {
      final updated = await client.agents.update(
        agent.id,
        UpdateAgentRequest(name: 'Updated research assistant'),
      );
      print(updated.name);
    } finally {
      await client.agents.delete(agent.id);
    }
  } finally {
    client.close();
  }
}

→ Full example

Durable agent sessions

Use client.agents.sessions to create sessions, observe events, and submit function results or cancellation. Cancelling a local event subscription stops observation only; cancel durable work explicitly through session inputs.

→ Full example

For reconnecting observers, subscribe with events.stream(..., onReady: ...), buffer updates, restore current session/history by item ID, then resume live handling. There is no replay cursor. Refresh requiredActions before an explicit browser decision; authentication values use only dedicated typed inputs with automatic retries disabled. An empty HTTP 202 confirms acceptance, so continue observing current state.

→ Offline browser actions and current-state recovery examples

How do I configure Agent context and action review?

Use AgentCompactionConfig(async: false) for blocking compaction and AgentExperimentalConfig(timeAwareness: true) for periodic current-time reminders. Compaction updates replace the configuration; null or {} restores background compaction. Experimental updates merge supplied keys, preserving omitted values. Request AgentServiceTierParam.ultrafast with a supported model when appropriate.

Set session review to SessionReviewParam.autoReview to review eligible actions automatically, or .none for existing execution behavior. Updates apply to new root turns; existing turns and their subagents keep their mode. Action review is independent of spending limits. Replace session tools through AgentSessionAgentUpdate; omission keeps them, while null or [] clears them. Function/MCP changes apply on the next model call, and built-in changes by the next turn.

Filter session lists with metadata: {'project': 'demo'}; all pairs must match, and updates may take time to appear in filtered results. Keep the same filters when advancing a cursor.

→ Offline settings and metadata-filter example

How do I schedule work with Agent automations?

Use client.agents.automations for one-time or cron schedules targeting a new session or an existing conversation. Creating, updating, pausing, and resuming a schedule do not invoke it immediately; call .invocations.create(automationId) explicitly for a manual delivery, including while paused.

Inspect .invocations.list or .retrieve for delivery status and the session ID. A completed delivery means the session accepted the input; follow session events for the Agent's result. Pausing or deleting a schedule leaves accepted session work running. Enable AgentTool.automations() or AgentSessionTool.automations() to let an Agent schedule follow-ups itself.

→ Offline schedule and invocation example

Follow one turn on an idle Agent session

Use this lazy helper with one application input writer. It retrieves idle state, subscribes before input, then observes the selected root turn through its terminal event and session idle. Raw sessions.events remains available for active-session steering and manual actions.

final run = client.agents.sessions.stream(
  sessionId,
  input: AgentSessionInitialInput.text('Continue the task.'),
);
try {
  await for (final event in run.events) {
    print(event.type);
  }
} finally {
  await run.close();
}

For sequential pulls that pause and continue, use run.nextEvent() instead of the Stream adapter. Stream break/close/abort stops only local observation; backend cancellation is a separate explicit raw input. Progress queues have bounded count/byte retention and fail on overflow.

→ Offline idle-run example

Handle local functions during an Agent turn

Keep canonical tool definitions in the saved Agent or creation request, then opt into local implementations separately. The original call event arrives before its handler runs; advancing the same cursor executes registered calls sequentially.

final run = client.agents.sessions.stream(
  sessionId,
  input: AgentSessionInitialInput.text('Double 2.'),
  toolHandlers: {
    'double_number': (args) => {'answer': (args['number']! as int) * 2},
  },
);
try {
  await for (final event in run.events) {
    // Render progress; unknown functions stay manual.
  }
} finally {
  await run.close();
}

Use sessions.createRun(request, toolHandlers: ...) for lazy streamed creation; explicit stream: false rejects locally. Callbacks stay out of wire JSON. Calls are deduplicated for the entire run, with a configurable 1,024-call budget that fails on overflow. Arguments must be JSON objects; failures send only Tool handler failed.. Optional onToolError receives private local details. Closing or aborting stops further submission; application side effects already performed are not undone. No executor, browser authentication or sandbox is added.

→ Offline local-tools example, with --create for creation

Collect or validate a completed Agent answer

finalResult() on a fresh run drains the same observation and returns completed root-turn messages. To render some progress first, enable collection before consumption and use the controlled cursor:

final run = client.agents.sessions.stream(
  sessionId,
  input: AgentSessionInitialInput.text('Summarize the task.'),
).withResultCollection();
try {
  final firstEvent = await run.nextEvent();
  final result = await run.finalResult();
  print(result.outputText);
} on AgentSessionRunResultException catch (error) {
  // Inspect error.reason, partial turn/messages/actions and cause explicitly.
} finally {
  await run.close();
}

Collection defaults to 1,024 final messages and 4 MiB of retained snapshots; overflow fails explicitly. Default progress retains no collector history. A Stream break closes observation; nextEvent() supports partial continuation. Failed/cancelled turns, unresolved actions and incomplete observation return private typed errors. After a manual action, available canonical clearing events can be drained; HTTP 202 alone does not prove the action finished.

Use run.withOutput(AgentSessionOutputBinding(format: ..., parse: ...)) before starting for typed output. Supply an Agents JSON schema and a synchronous local validator. Creation binds agent.text.format; follow-ups change no session configuration. Every completed text block must validate, and a parse failure preserves the successful raw result. Parsed application values remain owned by the parser. Result Futures cache success and failure without replaying work.

→ Offline raw/typed result example, including creation and parse failure

Session history and traces

Read session items, turns, and published OTLP traces through client.agents.sessions. Trace reads require organization export settings and permissions; a page contains only traces published when it is read.

→ Full example

Agent session subagents

Inspect child state and item/turn history through client.agents.sessions.subagents. These read-only methods do not create, resume, or interrupt child agents.

→ Full example

Agent environments and templates

Use client.agents.environments and .templates to save hosted setup and prewarm eligible environments. Environment and session lifetimes are independent; deleting a template does not stop a session. Eligible hosted sandboxes include the Artifact SDK and document skills inside the environment; prewarming uses the existing environment creation flow.

→ Full example

How do I upload Agent inputs and download result files?

Use AgentFiles(client).prepare(selected) to upload explicit bytes or streams with purpose=user_data, then pass prepared.files to AgentSessionEnvironment.openaiHosted(files: ...). Use .stage(environmentId, selectedFile) to copy one upload into an existing connected environment.

Bind downloads to a completed run result and an explicit binary sink:

final result = await run.withResultCollection().finalResult();
final artifacts = AgentResultArtifacts(client: client, result: result);
await artifacts.downloadTo(
  '/workspace/outputs/report.pdf',
  sink: (bytes) => outputSink.add(bytes),
);

The helper finds one exact session/turn/path match across every page. Callers own sink flush/close and upload cleanup; a failed preparation exposes observed IDs in AgentFilePreparationException.prepared. Streams are materialized one file at a time within a configurable local budget (64 MiB by default).

For explicit local files, import package:openai_dart/openai_dart_agent_files_io.dart. AgentFileSystem accepts paths beneath a stable application-owned directory and creates new output files only; it rejects overwrites and symlinks. Metadata checks cannot prove identity against same-metadata replacement, so this adapter requires stable directories.

→ Offline portable upload/result/download example · Optional local-file example

Agent environment files and published artifacts

Use client.agents.environments.files for live workspace files and client.agents.sessions.artifacts for published outputs. Download artifacts to retain them before deleting a session; use downloadStream for incremental bytes.

→ Full example

Vaults and write-only credentials

Use client.vaults and .credentials to store or rotate OAuth, bearer, and hosted environment secrets. Credentials are write-only; deleting a stored credential does not revoke its provider token or cancel running work.

→ Full example

Organization administration #

How do I use Admin keys, storage, and Decisions usage?

Use a separate OpenAIAdminClient. fromEnvironment() reads OPENAI_ADMIN_KEY; project client credentials and defaults are never inherited. Admin credentials are used only by this bounded administration namespace. Custom providers supply a Bearer Authorization header; configure organization/routing headers explicitly in OpenAIAdminConfig.

final admin = OpenAIAdminClient.fromEnvironment();
try {
  final usage = await admin.organization.usage.decisions(
    startTime: 1793404800,
    groupBy: [DecisionsUsageGroupBy.model, DecisionsUsageGroupBy.apiSource],
  );
  // Pass usage.nextPage as page explicitly when usage.hasMore is true.
  print(usage.data.length);
} finally {
  admin.close();
}

The 12 supported operations cover AWS/Azure/GCP external keys, AWS/Azure/GCP/OCI external storage, project API-key scope/relative-expiry updates, and Decisions usage. Empty key scopes means All permissions within the owner's effective access; eligible HTTP retries reapply relative expiry. Storage status and deletion effects remain service-owned. Historical Admin APIs are outside this slice. Redirects are disabled; automatic diagnostics redact key/provider metadata, IDs, and usage filters.

See the offline Admin example for synthetic key validation, OCI storage, service-account-owned key updates, and 30-minute cache-write usage. It uses only MockClient, with no real key registration, cloud access, or billing queries. The narrower import package:openai_dart/openai_dart_admin.dart is also available.

Legacy and retiring APIs #

What remains of the Videos API?

The Videos API and Sora 2 shut down on September 24, 2026. Retained types and this example are historical compatibility references. See the official deprecation schedule.

→ Historical example

What is the Evals retirement timeline?

Evals became read-only on October 31 and is scheduled to shut down on November 30, 2026. Plan a migration using the official retirement guidance. The retained example documents the historical API.

→ Historical example

Error Handling #

Handle API errors and retries

Catch typed exceptions such as RateLimitException, or ApiException for HTTP failures. OpenAIException also covers client and transport failures.

import 'package:openai_dart/openai_dart.dart';

Future<void> main() async {
  final client = OpenAIClient.fromEnvironment();

  try {
    await client.responses.create(
      const CreateResponseRequest(
        model: 'gpt-5.5',
        input: ResponseInput.text('Hello!'),
      ),
    );
  } on RateLimitException catch (error) {
    print('Rate limit: ${error.message}; retry hint: ${error.retryAfter}');
  } on ApiException catch (error) {
    print('HTTP ${error.statusCode}: ${error.message}');
  } on OpenAIException catch (error) {
    print('Client error: ${error.message}');
  } finally {
    client.close();
  }
}

Cloneable requests retry transient 429 responses; 5xx, timeout, and connection retries require an idempotent method. Billing/quota errors require action, and POST 5xx, multipart requests, and streams are not automatically replayed. Server retry hints are exposed as retryAfter; maxRetries: 0 disables automatic retries.

→ Full example · Retry and quota example

Examples #

Complete runnable workflows are in example/. Examples marked offline use local or mock transports; other examples can make paid API calls. Start with responses_example.dart.

Responses, Chat, Decisions, and embeddings
Example Description
vertex_responses_example.dart Offline. injected Google tokens, exact Vertex root and all six Responses lifecycle paths
runtime_config_example.dart Offline. configuration snapshots, refreshed handles and request-local credential rotation
responses_example.dart Responses API with built-in tools
openai_dart_example.dart Quick-start overview
web_search_example.dart Web search with Responses API
input_tokens_example.dart Input token counting
conversations_example.dart Conversations API for state management
chat_example.dart Chat completions, multi-turn conversations, and legacy cache retention
streaming_example.dart Content streaming, detailed final usage, and obfuscation controls
tool_calling_example.dart Function calling with tool definitions
vision_example.dart Image analysis with vision models
decisions_example.dart Typed Decisions questions, refusals, usage, and inline images
decisions_ga_example.dart Offline JSON evidence, tool history, multimodal questions, and shared-input caching
decision_image_urls_example.dart Offline. HTTP(S)/data image references, exact mixed input and one mock POST
embeddings_example.dart Text embeddings with dimension control
Images, audio, video, and live sessions
Example Description
images_example.dart GPT Image generation
image_model_selection_example.dart Local generation/multipart/JSON-edit model contracts without API calls
image_markup_example.dart Offline. PNG/reference overlays, safety identifiers and completed edit events
audio_example.dart Text-to-speech and transcription
speech_streaming_example.dart Offline. buffered/byte/SSE speech, voice references and usage
existing_audio_example.dart Offline. modern file fields, verbose/raw translation, open/custom Chat voices and AAC
chat_audio_example.dart Chat audio output, ID-only replay, and partial stream accumulation
videos_example.dart Historical Videos API reference; endpoint retired
realtime_example.dart Realtime API (WebSocket and WebRTC)
realtime_input_example.dart Offline. acknowledged history references, typed new input and out-of-band response output
realtime_translation_example.dart Offline. scoped translation secret, noise strength, typed audio/transcripts and flush/close
live_http_example.dart Offline. WebRTC/SIP signaling, explicit call controls, verified incoming notice, WAV downloads and REST fork
live_media_example.dart Offline. raw audio fixture acceptance/drain, independent mute, and SIP DTMF directions
live_websocket_example.dart Offline. primary/sideband Live, concurrent event taps, manual delegation and graceful finalization
live_decisions_example.dart Offline. native Decisions delegation, shared items, and a correlated transcript trigger
live_workflows_example.dart Offline. stored forks, inherited state, compact Responses, caption grouping and borrowed-channel cleanup
voice_consents_example.dart Offline. upload/list/retrieve/rename/delete consent lifecycle and explicit pagination
voices_example.dart Offline. explicit consent and sample upload, then caller-selected custom voice reference
prompt_voices_example.dart Offline. create a prompt voice, select it for Live, and explicitly delete it
Files, batches, errors, webhooks, and safety
Example Description
files_example.dart File upload and management
uploads_example.dart Large file multipart uploads
batches_example.dart Batch processing for async jobs
fine_tuning_example.dart Fine-tuning job management
evals_example.dart Historical Evals reference; read-only until November 30, 2026
models_example.dart Model listing and retrieval
moderation_example.dart Content moderation
content_provenance_checks_example.dart Content provenance (C2PA/SynthID) detection
error_handling_example.dart Exception handling patterns
retry_guidance_example.dart Local transient, permanent-quota, and long-hint scenarios without API calls
agent_environment_webhooks_example.dart Offline. environment subscriptions, signed notifications, repeated-ID handling and safe retrieval
webhooks_example.dart Offline. signed receiver, acknowledgment and caller-owned deduplication
webhook_endpoints_example.dart Offline. project endpoint lifecycle, pagination, discovery, rotation and test status
safety_example.dart Offline. verified notifications and separately scoped alert/case retrieval
safety_explanations_example.dart Offline. project alert explanation presence, copy/clear and private diagnostics
monitoring_errors_example.dart Offline. typed HTTP/SSE monitoring failures and explicit scoped investigation
Advanced Responses workflows
Example Description
responses_websocket_example.dart Offline. low-level warmup, two persistent lanes and incremental continuation
responses_websocket_session_example.dart Offline. bounded sessions, manual tool continuation, fork barrier and compact replay
responses_steering_example.dart Offline. steer a running Responses request
responses_recovery_example.dart Offline. recover a Responses WebSocket
websocket_recovery_example.dart Local peer. reconcile a Realtime session before flushing pending work
async_tools_example.dart Local async function/custom jobs, original call IDs and latest-response continuation
tool_search_example.dart Offline. client tool-search continuation with the original call ID and complete discovered definitions
web_search_controls_example.dart Local GA filters, image results, sources, and REST/SSE parsing without API calls
reasoning_replay_example.dart Offline. typed reasoning and function history replay with opaque state and original ordering
configuration_updates_example.dart Offline. change reasoning effort during a conversation
prompt_cache_example.dart Responses prewarming, comparison diagnostics, and narrow Chat cache options
responses_cache_usage_example.dart Offline 30m/12h cache boundaries and separate hosted-tool usage
containers_example.dart Container memory/network configuration, Code Interpreter IDs, and files
shell_tools_example.dart Offline. hosted configuration, synthetic local continuation, and typed shell stream events
compaction_progress_example.dart Offline. nonterminal compaction progress and opaque final output preservation
access_programs_example.dart Offline. access-program selection, server defaults and effective returned metadata
responses_injection_example.dart Offline. inject multi-agent tool results
Agents, Vaults, and other resources
Example Description
saved_agents_example.dart Offline. saved-agent CRUD, tool configuration, pagination, replacement and clear/reset
agent_settings_example.dart Offline. compaction, time awareness, session review/tools, ultrafast and exact metadata filters
agent_automations_example.dart Offline. once/cron schedules, new/existing session targets, pause/resume, explicit invocation and delivery history
agent_sessions_example.dart Offline. durable sessions, persistent observation, manual function result and explicit cancellation
agent_browser_actions_example.dart Offline. explicit origin decisions, private authentication and observed acceptance
agent_session_recovery_example.dart Offline. subscribe/buffer, current-state/history reconciliation and local observer cleanup
agent_session_run_example.dart Offline. lazy idle follow-up, selected root boundary, controlled pulls and separate cancellation
agent_local_tools_example.dart Offline. opt-in sequential function dispatch for streamed creation or idle follow-up
agent_session_result_example.dart Offline. raw/typed completed results, partial cursor continuation and local parse failure
agent_session_history_example.dart Offline. root/turn history and published OTLP trace pagination
agent_subagents_example.dart Offline. Agent session subagents
agent_environments_example.dart Offline. template CRUD and owned hosted environment prewarming, pagination and safe inspection
agent_file_helpers_example.dart Offline. selected bytes, explicit staging, completed run identity and binary artifact sink
agent_files_io_example.dart Local only. explicit regular-file selection beneath an application-owned directory; no API calls
agent_files_artifacts_example.dart Offline. Agent environment files and published artifacts
admin_example.dart Offline. isolated Admin credentials, external keys, OCI storage, key updates, and Decisions usage
vaults_example.dart Offline. Vault CRUD and write-only credential create/rotate with safe inspection
chatkit_example.dart ChatKit sessions and threads
skills_example.dart Skills management
assistants_example.dart Historical Assistants reference; endpoint retired
completions_example.dart Legacy completions API

API Coverage #

Supported APIs and remaining gaps
API Support
Responses HTTP and SSE, persistent WebSockets, bounded lane sessions, steering, opt-in connection recovery, and beta tool-result injection
Chat Completions Generation and streaming; stored-completion management pending
Decisions Predicate, choice, and score questions
Embeddings Text vectors with dimension control
Images Generation, editing, and streaming
Audio Speech, transcription, translation, voice consents, prompt/sample voice creation, and saved voice deletion; consent phrase lookup remains untyped
Videos Retained compatibility types; API shut down September 24, 2026
Realtime WebSocket and WebRTC sessions, typed response input references, noise strength, Translation sockets, and opt-in recovery with explicit pending delivery
Live HTTP call controls, recordings, WebSockets, native Decisions delegation/triggers, audio fixtures, SIP DTMF, forks, transcript helpers, and opt-in recovery with fresh startup gating
Files and Uploads File management and large multipart uploads
Batches Asynchronous batch processing
Models Listing and retrieval
Moderations Text and image moderation
Fine-tuning Job management; some grader/checkpoint operations pending
Evals Read-only since October 31; scheduled shutdown November 30, 2026
Conversations Conversation and item management
Containers Memory, network policy, skills, and files
Content Provenance Checks C2PA and SynthID inspection
Webhooks Local signed verification and project endpoint management
Safety Read-only project alerts, organization cases, and typed monitoring details
Agents Saved agents, context settings, action review, durable sessions, scheduled automations and invocations, metadata filters, root/child history, hosted environments, portable file preparation, explicit staging, and completed-result artifacts
Vaults Vault management and write-only credentials
Organization Admin Separate Admin credentials; external keys/storage, project API-key updates, and Decisions usage (12 operations)
ChatKit Beta and Skills Sessions/threads and skills management
Assistants, Threads, Messages, and Runs Historical types; Assistants API retired; separate import
Vector Stores File search storage and ingestion; separate Assistants import
Completions Legacy compatibility API; prefer Responses

Some Responses tool/configuration details and historical administration APIs remain outside current coverage. See the completed October alignment and remaining limits for the detailed scope.

Official Documentation #

If these packages are useful to you or your company, please consider sponsoring the project. Your support helps maintain the packages and fund API integration tests for the Dart and Flutter community.

License #

This package is licensed under the MIT License.

This is a community-maintained package and is not affiliated with or endorsed by OpenAI.

139
likes
160
points
46.8k
downloads

Documentation

API reference

Publisher

verified publisherdavidmiguel.com

Weekly Downloads

Dart client for the OpenAI REST APIs and realtime WebSocket/WebRTC workflows with type-safe access to GPT, image, audio, and Responses APIs.

Homepage
Repository (GitHub)
View/report issues

Topics

#nlp #gen-ai #llms #openai #gpt

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

crypto, http, http_parser, logging, meta, web_socket

More

Packages that depend on openai_dart