Skip to content
anecticoDocsDashboard
Browse documentation
Reference

Flutter SDK API

Functions, options, parameters, futures, and native behavior for the Anectico Flutter SDK.

On this page

anectico_flutter bridges Dart to the native iOS and Android SDKs. Native code owns identity, sessions, persistence, transport, and native crashes; Dart adds Flutter framework and uncaught async error capture. Configuration failures, including a missing native plugin, fail the returned future; subsequent telemetry calls remain best-effort and swallow channel failures.

Use a project key with ingest:write and analytics:write. Flutter replay is not supported.

Configure and shut down

await Anectico.configure(
  const AnecticoOptions(
    apiKey: 'an_...',
    environment: 'production',
    serviceVersion: '1.4.0',
  ),
);
API Parameters Returns Behavior
Anectico.configure(options) AnecticoOptions Future<void> Configures native state and installs Dart handlers unless disabled. The future fails for invalid options or a missing native plugin, and isConfigured remains false.
Anectico.flush() — Future<bool> Flushes the native event queue and resolves whether every batch it attempted was accepted. See Knowing whether your events arrived.
Anectico.shutdown() — Future<bool> Removes Dart/native hooks, flushes, and releases resources. Resolves the final flush's outcome, like flush.
Anectico.configure(options, resumeAnalyticsCollection: true) Explicit new consent after awaited shutdown Future<void> Purges all old analytics queue data before reopening collection; failures reject configuration.
Anectico.disableAnalytics() — Future<bool> Persist analytics withdrawal and purge queued data; await the result before relying on the native gate.
Anectico.stats() — Future<AnalyticsStats> Delivery counters — recorded, delivered, dropped, queued. Zeros before configure.
Anectico.deliveryErrors property Stream<DeliveryError> Emits once per permanently discarded batch with status, dropped, and reason.
Anectico.isConfigured property bool Dart-side view of whether configure completed. Diagnostic use only.
AnecticoFlutter.installErrorCapture() — void Installs and chains FlutterError.onError and PlatformDispatcher.onError.
AnecticoFlutter.uninstallErrorCapture() — void Restores prior handlers when they are still owned by Anectico.
AnecticoFlutter.isErrorCaptureInstalled property bool Whether Dart hooks are currently installed.

Await Anectico.disableAnalytics() when analytics consent is withdrawn. The native SDK closes analytics admission, including capture, identify, group, reset, and lifecycle events, and discards pending events without flushing them. Errors, crashes, agent traces, and OTLP logs have separate controls and continue. An already-admitted request can still reach the server: validated receipt outcomes remain credited; uncertain retries and unsent remainder are discarded with collection_disabled and status 0. This does not erase previously accepted data. recorded = delivered + dropped + queued remains true.

A true result confirms both the persistent withdrawal marker and deletion of the analytics spool. On false, this configured client stays disabled, but persistence/purge needs retry; do not assume restart safety until a retry succeeds. Await the future before relying on the native admission fence. A missing plugin or channel failure returns false. Ordinary configuration preserves the marker across restart. Only after obtaining new consent, await Anectico.shutdown(), then call await Anectico.configure(options, resumeAnalyticsCollection: true). Explicit renewal purges all old analytics queue data even when the marker is absent; a purge failure fails configuration. Repeated configuration of an already configured SDK does not renew consent. Wait for shutdown completion before reconfiguring; configuration during retirement fails.

Knowing whether your events arrived

flush returns true only when every attempted product-event position has a validated queued acknowledgement. An empty queue succeeds. This is evidence of queue acceptance; it does not prove query visibility, unique stored rows, or identity application. Errors and crash reports use a separate pipeline.

A complete version-one receipt classifies each original position before the SDK updates its queue or counters:

Receipt outcome Your events flush Queue and callback
queued removed from the pending queue succeeds if all positions were queued increments delivered
rejected refused positions are discarded failure increments dropped; fires a drop callback
unknown, malformed, truncated, oversized, or absent receipt uncertain positions remain pending failure retains original message IDs; no drop callback

Typed permanent request failures also discard the attempted batch. Network failures, rate limits, and dependency failures retain it. Repeated uncertainty backs off from one second to 60 seconds; a fully settled receipt resets that delay. Server retry hints are clamped to that range.

Anectico.stats() reports recorded, delivered, dropped, and queued; recorded equals the other three added together. delivered counts validated queue acknowledgements, not unique stored events.

The Anectico.deliveryErrors stream reports the number of discarded events once per affected chunk. A batch receipt can refuse events with HTTP 200: invalid_event, quota_exceeded, or mixed_rejection. Typed request failures use bad_request, unauthorized, forbidden, not_found, payload_too_large, unprocessable, or rejected. Local queue_overflow and not_serializable drops carry status 0. Unknown outcomes remain queued without a callback unless explicitly discarded on withdrawal with collection_disabled. An unrecognized reason maps to DeliveryErrorReason.unknown, preserving the original code in rawReason.

Capturing stays non-blocking: capture, identify, group, and screen queue the event and return immediately, so the delivery outcome reaches you through the three signals above and never through their own return value.

Anectico.deliveryErrors.listen((DeliveryError error) {
  debugPrint('lost ${error.dropped} events: ${error.rawReason} (HTTP ${error.status})');
});

if (!await Anectico.flush()) {
  final AnalyticsStats stats = await Anectico.stats();
  // stats.queued > 0 means a retry is pending; otherwise the events are gone.
}

When the plugin is not installed in the running app, flush() and shutdown() resolve false and stats() reports zeros — nothing was delivered, so nothing is reported as accepted.

AnecticoOptions

Only apiKey is required. Null fields are omitted across the channel so native defaults apply. Invalid endpoints, timers, capacities, frame limits, and non-finite or out-of-range sampling values fail configuration instead of being clamped.

Option Type/default Purpose
apiKey String; required Error/event API key.
endpoint String?; native https://api.anectico.com API base URL.
environment String?; native development Deployment environment.
release, dist String? Release and artifact identifiers.
serviceName, serviceVersion String? Native resource identity; defaults from the app.
flushAt int?; native 20 Event-count flush threshold.
flushIntervalMs int?; native 5000 Foreground-only native periodic flush; zero disables it.
maxStackTraceFrames int?; native 50 Dart/native frame cap.
breadcrumbCapacity int?; native 100 Native breadcrumb capacity.
maxQueueSize int?; native 10000 Native event queue cap.
errorSampleRate double?; native 1 Non-fatal error sampling from 0–1.
enableCrashReporting bool?; native true Install native crash handlers.
debug bool?; native false Native diagnostic logging.
enableDartErrorCapture bool; true Dart-only automatic error handlers.

Identity, accounts, and events

Method Parameters Returns Behavior
Anectico.identify(distinctId, {set}) stable ID; person properties Future<void> Links anonymous and known identity.
Anectico.group(type, key, {set}) account type/key; properties Future<void> Records membership and $groupidentify.
Anectico.capture(event, {properties}) event; properties Future<void> Queues a durable diagnostic event, natively stamped with the reserved $release/$app_version properties (see Reserved event properties) when configure() set release/serviceVersion.
Anectico.screen(name, {properties}) screen; properties Future<void> Queues $screen and $screen_name.
Anectico.reset() — Future<void> Logout: rotates native identity/session and clears groups, global error-user context, and breadcrumbs.
Anectico.getDistinctId() — Future<String> Current identity or empty string.
Anectico.getSessionId() — Future<String> Current session without extending idle lifetime, or empty string.

Agent runs

Anectico.startAgentRun(AgentRunOptions options) synchronously returns a one-shot AgentRun.

final run = Anectico.startAgentRun(const AgentRunOptions(
  agent: 'checkout-helper',
  agentId: 'checkout',
  agentVersion: '1.4.0',
  conversationId: 'chat-42',
));
// Perform the agent's work, then declare its actual outcome.
await run.end(AgentRunTerminalStatus.completed);
// On failure instead:
// await run.end(AgentRunTerminalStatus.failed, terminalReason: 'tool_failed');

AgentRunOptions.agent is required. agentId, agentVersion, and conversationId are optional strings mapping to gen_ai.agent.id, gen_ai.agent.version, and gen_ai.conversation.id. The agent name maps to gen_ai.agent.name. Configure and identify the customer before starting a run. A terminal record is an invoke_agent span sent with ingest:write; it does not require an agent-read or agent-write management scope. It is not automatic instrumentation of nested model/tool calls.

end(AgentRunTerminalStatus status, {String? terminalReason}) returns Future<void>, not a delivery boolean. Status is required: completed, failed, timedOut, cancelled, or maxSteps; multiword wire values are timed_out and max_steps.

Use a stable, non-sensitive reason code, not an exception message, prompt, or customer value. Reasons are trimmed, lowercased, and must match ^[a-z][a-z0-9_]{0,63}$. Omitted reasons default to timeout for a timeout, user_cancelled for cancellation, and the wire status for other outcomes. These are source-declared outcomes; Anectico does not infer success from the absence of an error.

An invalid reason fails the future with ArgumentError and leaves the handle open. A native false result completes the future but leaves the handle open for a later retry; channel failures are handled by the native bridge wrapper. Concurrent end calls share the in-flight future. After native acceptance, later valid calls do nothing. Completion is not network-delivery confirmation. Native identity is attached at completion, so end the run before resetting or switching customers.

Errors, messages, users, and breadcrumbs

Method Parameters Returns Behavior
Anectico.captureError(error, stackTrace, {options}) object; optional stack; options Future<String?> Parses Dart frames and forwards a caught error to native. Only options.tags applies to this bridge path.
Anectico.captureMessage(message, {level, options}) text; level default info; options Future<String?> Native message capture with full options fidelity.
Anectico.addBreadcrumb(category, message, {level, data}) fields Future<void> Adds native trail context for the next error.
Anectico.setUser(user) AnecticoUser Future<void> Sets global error user context.
Anectico.clearUser() — Future<void> Clears error user context.

CaptureOptions fields are tags, extra, user, level, and fingerprint. Only tags is used by captureError; all fields can be used by captureMessage. AnecticoUser fields are id, email, username, ipAddress, and segment. Breadcrumb constants live in AnecticoBreadcrumbLevel.

Automatic handlers use mechanisms AnecticoMechanism.frameworkError and AnecticoMechanism.platformDispatcher. They forward to the prior handler afterward, preserving normal Flutter behavior. Native fatal crashes are handled by the underlying SDK.

The native transport adds SDK-owned app/build, OS, and privacy-safe hardware-model context. It does not collect stable device identifiers or user-assigned device names.

Backend propagation

Anectico.propagationHeaders(): Future<Map<String,String>> returns a fresh W3C traceparent and current identity baggage. Send it only to a trusted application backend. The backend must authenticate the request independently.

Stack utility exports

The package exports AnecticoFrame, parseStackTrace, parseStackString, framesToJson, and maxDartFrames for custom error integrations. Normal application code should call Anectico.captureError, which uses those helpers automatically.

Anectico does not currently symbolicate Dart frames obfuscated with --obfuscate. Retain Flutter debug information and use flutter symbolize outside Anectico for those builds.

Native capture receipt migration

Both bundled native sources now validate complete version-one indexed capture acknowledgements. Mixed receipts retire queued and refused positions while retaining uncertain original events in their durable spools. Malformed or incomplete responses remain uncertain. Ledger refusals can carry HTTP 200 with invalid_event, quota_exceeded, or mixed_rejection; those codes cross this bridge. Without a hint, native retry delay doubles from one second to a 60-second cap until a receipt fully settles. Retry-After is clamped to 1–60 seconds. Published-package, device and backend qualification remains open; this is not a completed release.