Package selection guidance compiled from public package information, community data, and project usage.
The dart_openai package provides a Dart SDK for integrating OpenAI's advanced AI models, including GPT-3 and DALL-E, into Dart applications. It enables seamless communication with OpenAI's APIs, allowing developers to generate text, create images, and implement conversational AI features. The package supports multiple platforms such as Android, iOS, macOS, Windows, and Linux, making it ideal for cross-platform apps. With straightforward API access and clear documentation, it simplifies the integration of generative AI capabilities into Flutter and other Dart-based projects.
Use cases
Text generation with GPT-3
Image creation using DALL-E
Building AI-powered chatbots
Integrating AI into mobile and desktop apps
Creating content automation tools
Key features
Supports GPT-3 and DALL-E APIs
Cross-platform compatibility
Simple and intuitive Dart interface
Real-time API interaction
Comprehensive error handling
Suitable for
Flutter developers
AI application creators
Full-stack developers
Startups building AI features
Educational or prototyping projects
Considerations
Requires an OpenAI API key
Rate limits apply based on subscription
Network connectivity needed
Potential latency in API responses
Costs associated with usage beyond free tier
Original README
Original README snapshot from the linked source repository. Visit the repository for the latest content.
dart_openai
Unofficial Dart/Flutter SDK for the OpenAI API. Typed clients for every major API surface: Responses, Chat Completions, Realtime, Videos, Batch, Fine-tuning, Vector Stores, Evals, Administration and more. Compiles and runs on every platform: Android, iOS, macOS, Linux, Windows, web, and server-side Dart.
Every OpenAIClient owns its configuration. Run several accounts, Azure resources, or OpenAI-compatible providers side by side without global state:
final production = OpenAIClient(apiKey: 'sk-prod');
final deepseek = OpenAIClient(
apiKey: 'ds-...',
baseUrl: 'https://api.deepseek.com',
);
final localLlama = OpenAIClient(
apiKey: 'not-needed',
baseUrl: 'http://localhost:1234/v1',
);
Works with any provider that implements the OpenAI wire format: DeepSeek, LM Studio, Ollama, Groq, Together, Azure OpenAI gateways, and others.
Streaming
One SSE engine backs every streaming endpoint. It closes on [DONE], never duplicates events, and surfaces errors as exceptions instead of swallowing them.
Responses API events:
final events = client.responses.createStream(
model: 'gpt-4o',
input: 'Write a haiku about databases.',
);
awaitfor (final event in events) {
if (event['type'] == 'response.output_text.delta') {
stdout.write(event['delta']);
}
}
Chat Completions deltas:
final chunks = client.chat.createStream(model: 'gpt-4o', messages: messages);
awaitfor (final chunk in chunks) {
stdout.write(chunk.choices.first.delta?.content);
}
Images emit partial results as they render (createStream), and stored completions support retrieval and listing.
Not planned: Assistants v1 and Threads (superseded by the Responses API), ChatKit.
Resilience
Requests retry automatically on transient failures (connection errors, HTTP 408/429/5xx). GET requests always retry; POST retries only on rate limits and server errors. Backoff is exponential with jitter and the server's Retry-After header takes precedence.
Streaming has an idle watchdog: a connection that stops delivering bytes fails with StreamTimedOutException after the request timeout instead of hanging forever. After any call, quota is observable:
final azure = OpenAIClient(
apiKey: '<azure-key>',
azure: constOpenAIAzure(
resource: 'my-resource',
apiVersion: '2024-10-21',
deployments: {'gpt-4o': 'gpt4o-prod'},
),
);
// model is rewritten to your deployment automatically:await azure.chat.create(model: 'gpt-4o', messages: messages);
Files on every platform
Upload APIs take a platform-neutral file type — no dart:io, so the same code runs on web:
// From disk (native):final file = awaitloadOpenAIFile('training.jsonl');
await client.file.upload(file: file, purpose: 'fine-tune');
// From memory (anywhere, including web):await client.file.uploadBytes(
bytes: utf8.encode(jsonl),
fileName: 'training.jsonl',
purpose: 'fine-tune',
);
Error handling
All failures throw typed exceptions you can catch precisely:
try {
await client.chat.create(model: 'gpt-4o', messages: messages);
} onRequestFailedExceptioncatch (e) {
// Non-2xx from the API: e.message, e.statusCode
} onMissingApiKeyExceptioncatch (e) {
// No key configured for this client
} onOpenAIUnexpectedExceptioncatch (e) {
// Malformed response that is not an API error payload
}
Error payloads are normalized across providers. Whether a provider returns {"error": {"message": ...}}, a bare string error, or an HTML error page, you get a RequestFailedException with the body preserved.
Global facade equivalents: OpenAI.apiKey, OpenAI.organization, OpenAI.baseUrl, OpenAI.requestsTimeOut, plus OpenAI.showLogs and OpenAI.showResponsesLogs for request debugging.
Reasoning models (o-series, GPT-5 family): pass reasoningEffort: 'low' and use maxTokens, which maps to max_completion_tokens. Incompatible sampling parameters are rejected by the API; use extraParams to pass anything not yet modeled.
Migrating from 6.x / 7.x
Nothing breaks if you used the global facade. To adopt per-client instances, replace global configuration with construction:
8.0.0 replaces dart:io File parameters with the platform-neutral OpenAIFile type (await loadOpenAIFile(path) on native, OpenAIFile(bytes:, fileName:) anywhere), and audio.createSpeech now returns bytes.
The suite runs entirely against mocked HTTP — request shapes, SSE decoding, malformed-payload fuzzing, retry behavior. No API keys required:
dart test
Live integration tests run only when OPEN_AI_API_KEY is present in the environment.
Contributing
Bug reports and feature requests go through GitHub Issues. Pull requests welcome: keep diffs focused, add or update tests for changed behavior, and follow the existing module layout (lib/src/instance/<module>/ with models under lib/src/core/models/<module>/). Commit messages use Conventional Commits.