Documentation

Flutter

Add the replicate_interceptor package to your Flutter app to enable recording and intercept mode.

Note: ReplicateInterceptor.init() is a no-op in release builds. It is safe to leave in your production code — it will never intercept network calls in a release build.

Installation #

Add the package to your pubspec.yaml. View it on pub.dev.

yaml
dependencies:
  replicate_interceptor: ^0.1.0

Then fetch dependencies:

bash
flutter pub get
cd ios && pod install  # if targeting iOS

Setup #

Call ReplicateInterceptor.init() as the very first thing in main(), before runApp() and before any network calls:

dart
// main.dart — before everything else
import 'package:replicate_interceptor/replicate_interceptor.dart';

void main() async {{
  WidgetsFlutterBinding.ensureInitialized();
  await ReplicateInterceptor.init();
  runApp(const MyApp());
}}
Order matters: init() must be called after WidgetsFlutterBinding.ensureInitialized() but before runApp(). Any network calls that happen before init() resolves will not be captured.

How it works #

The interceptor reads a session config file that Replicate writes into your simulator app's Documents directory before launching. If the file is absent (normal development, CI), the interceptor stays inactive and has zero overhead.

Based on the mode in the session config, the interceptor either records, intercepts, or simply restores keychain state:

Session config reference #

Replicate writes this file to <AppContainer>/Documents/replicate_session.json before launching your app:

json
{
  "sessionId": "uuid",
  "mode": "record | intercept | dump_keystore | restore_only",
  "restoreKeystore": false
}

Modes #

ModeWhat it does
recordIntercepts all HTTP calls, writes tape files + keystore dump to Documents
interceptLoads override files, modifies requests/responses per your rules; manual tape entries are served locally
dump_keystoreExports flutter_secure_storage entries to a JSON file, then stays inactive
restore_onlyRestores keystore entries from file, then stays inactive with no network interception

Tape file format #

Each recorded request is saved as a separate JSON file in Documents/replicate_tape/<uuid>.json:

json
{
  "id": "uuid",
  "method": "GET",
  "url": "https://api.example.com/v1/cart",
  "requestHeaders": {{}},
  "requestBody": null,
  "requestBodyEncoding": "utf8",
  "statusCode": 200,
  "responseHeaders": {{}},
  "responseBody": "{...}",
  "responseBodyEncoding": "utf8",
  "timestamp": "2026-01-01T00:00:00Z",
  "durationMs": 142,
  "isSuccess": true,
  "source": "record"
}
Encoding note: Text content types (application/json, text/*, application/xml) are stored as utf8. Binary content (images, multipart uploads, protobuf) is stored as base64 with the encoding field set to "base64".

Keystore format #

Keychain entries from flutter_secure_storage are exported as a flat key–value map:

json
{
  "entries": {{
    "access_token": "eyJhbGci...",
    "user_id": "12345"
  }}
}}

Troubleshooting #

SymptomSolution
Interceptor not recording Make sure init() is called before runApp(). Confirm that Replicate has started a recording session before launching the app.
Works in debug but not release Expected — the interceptor is a no-op in release builds by design.
Keystore not captured Only flutter_secure_storage is supported. Other storage libraries are not captured.
Network calls missing from tape Calls made before init() completes will not be captured. Move init() earlier in main().