Flutter API Calls with Dio: Setup and Patterns
Dio is the most widely used HTTP client in Flutter. Here's how I set it up — interceptors for auth, error mapping, and cancellation — without overengineering.
Dio is the de facto HTTP client for Flutter. Out of the box it works fine. The wins come from setting up interceptors and consistent error handling once, then leaving them alone.
Base configuration
dartfinal dio = Dio(BaseOptions(
baseUrl: 'https://api.example.com',
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 10),
responseType: ResponseType.json,
headers: {'Accept': 'application/json'},
));Auth interceptor
Add an interceptor that attaches the auth token on every request and refreshes it when the server returns 401. Centralizing this means individual repository methods do not need to know about auth at all — they call dio.get() and the interceptor handles the rest.
Error mapping
Wrap Dio calls in a function that converts DioException into your own typed errors (ApiError.network, ApiError.unauthorized, ApiError.server). Repositories return Either or AsyncValue with these typed errors instead of raw exceptions. The UI now has a small, named set of failures to handle.
Cancellation
Pass a CancelToken to long-running requests, and cancel it when the widget is disposed or the user changes inputs. This avoids the classic bug where a slow search request returns after the user has typed something different and replaces the new results.
The whole setup — base URL, interceptors, error mapping, cancellation — is roughly 80 lines of code. Done once, every call site stays clean.
About the author

Richard Gamora
Fullstack developer based in the Philippines, working mostly with Laravel and Vue.js, with eight years of production experience across web and mobile.
More on Flutter
November 19, 2025
Flutter State Management in 2026: Honest Comparison
Provider, Riverpod, BLoC, GetX — Flutter has many state management options. Here's how I actually pick between them for real apps.
November 12, 2025
Flutter Riverpod 2: Practical Patterns for Real Apps
Riverpod 2 with code generation is the most ergonomic way to manage state in Flutter today. Here are the patterns that hold up in production apps.
November 5, 2025
Migrating a Flutter App to Null Safety: Lessons Learned
Migrating an existing Flutter codebase to null safety is mostly mechanical — but a few patterns require real thinking. Here's a practical playbook.