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, audio, and video generation.
  • Built-in web search, file search, Code Interpreter, computer use, and custom tools.
  • Files, batches, fine-tuning, evals, 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: ^11.0.1
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.

Imports for Realtime and deprecated Assistants APIs

The main import is package:openai_dart/openai_dart.dart. Realtime uses package:openai_dart/openai_dart_realtime.dart; deprecated Assistants resources use package:openai_dart/openai_dart_assistants.dart.

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

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; input supports text and HTTP(S) or data URL images.

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 · 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, audio, and video

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();
  }
}

→ Full example · Model selection

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 videos?

Use client.videos.create to start a video job, poll retrieve until completion, then download with retrieveContent. The example also covers editing and extension.

→ Full example

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?

Use client.audio.voices with a consent ID and an audio sample. Pass the returned voice ID to speech requests as a custom voice reference.

→ Full 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

How do I evaluate models?

Use client.evals to define grading criteria and run evaluations against test data.

→ 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

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 a persistent connection with named response lanes. Continue with returned response IDs and await connection cleanup; browser connections require an authenticated backend proxy because WebSockets cannot send API-key headers.

import 'dart:io';

import 'package:openai_dart/openai_dart.dart';

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

  try {
    final connection = await client.responses.connect();
    try {
      connection.create(
        const CreateResponseRequest(
          model: 'gpt-5.5',
          input: ResponseInput.text('Tell me a short joke.'),
        ),
      );
      await for (final message in connection.events) {
        if (message case ResponsesStreamEvent(
          event: OutputTextDeltaEvent(:final delta),
        )) {
          stdout.write(delta);
        } else if (message case ResponsesStreamEvent(
          event: ResponseCompletedEvent(),
        )) {
          break;
        } else if (message case ResponsesStreamEvent(
          event: ResponseFailedEvent() || ResponseIncompleteEvent(),
        )) {
          throw StateError('The response did not complete.');
        } else if (message is ResponsesErrorEvent) {
          throw StateError('Response failed: ${message.error.code}');
        }
      }
    } finally {
      await connection.close();
      await connection.done;
    }
  } finally {
    client.close();
  }
}

→ Full example

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.

→ 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 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.

→ Full example

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');
    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 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 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 replace supplied fields, while clearX flags reset nullable fields.

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

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.

→ Full 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

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
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
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
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 Sora video generation, editing, and extension
realtime_example.dart Realtime API (WebSocket and WebRTC)
live_http_example.dart Offline. WebRTC/SIP signaling, explicit call controls, verified incoming notice, WAV downloads and REST fork
live_websocket_example.dart Offline. primary/sideband Live, concurrent event taps, manual delegation and graceful finalization
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
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 Model evaluation and testing
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
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. warm-up, two persistent lanes and incremental continuation with awaited cleanup
responses_steering_example.dart Offline. steer a running Responses request
responses_recovery_example.dart Offline. recover a Responses WebSocket
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
configuration_updates_example.dart Offline. change reasoning effort during a conversation
prompt_cache_example.dart Responses prewarming, comparison diagnostics, and narrow Chat cache options
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, all six persisted tools, pagination, replacement and clear/reset
agent_sessions_example.dart Offline. durable sessions, persistent observation, manual function result and explicit cancellation
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_files_artifacts_example.dart Offline. Agent environment files and published artifacts
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 Assistants API (deprecated)
completions_example.dart Legacy completions API

API Coverage

Supported APIs and remaining gaps
API Support
Responses HTTP and SSE, persistent WebSockets, steering, opt-in 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, and custom voices; consent phrase lookup remains untyped
Videos Generation, editing, extension, and downloads
Realtime WebSocket and WebRTC sessions through a separate import
Live HTTP call controls, recordings, WebSockets, forks, and transcript helpers; some media/reconnect conveniences remain deferred
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 Evaluation definitions and runs
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, durable sessions, root/child history, published traces, hosted environments, templates, files, and artifacts
Vaults Vault management and write-only credentials
ChatKit Beta and Skills Sessions/threads and skills management
Assistants, Threads, Messages, Runs, and Vector Stores Deprecated; separate Assistants import
Completions Legacy text completions

Some Responses tool/configuration details, Agents helper workflows, and administration APIs remain outside current coverage. See the API alignment inventory 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.

Libraries

openai_dart
Dart client for the OpenAI API.
openai_dart_assistants
Deprecated Assistants API for OpenAI.
openai_dart_realtime
Realtime API for OpenAI.