SDK behavior
All Ferry SDKs implement the same integration contract even when the platform APIs use different language conventions.
Core surface
| Job | iOS | Android | Flutter | React Native |
|---|---|---|---|---|
| Configure | Ferry.configure | Ferry.configure | Ferry.configure | Ferry.configure |
| Receive links | Ferry.onLink | Ferry.onLink | Ferry.onLink stream | Ferry.onLink |
| Receive installation result | Ferry.onInstallation | Ferry.onInstallation | Installation stream | Ferry.onInstallation |
| Handle a URL | Ferry.handle | Ferry.handle | Ferry.handle | Ferry.handle |
| Track events | Ferry.track | Ferry.track | Ferry.track | Ferry.track |
| Force a batch flush | Ferry.flush | Ferry.flush | Ferry.flush | Ferry.flush |
| Create a client link | Ferry.createLink | Ferry.createLink | Ferry.createLink | Ferry.createLink |
Link delivery
Every SDK delivers one logical link model:
| Field | Meaning |
|---|---|
data | Customer-defined string-to-string payload |
url | Optional trusted fallback or context URL |
clickId | Ferry attribution metadata managed by the SDK |
method | Open-ended attribution method value |
confidence | Deterministic or probabilistic confidence |
isDeferred | true for a first-install match, false for a direct open |
installation | Optional attributed or organic first-open result |
Register the link listener once and early. The first registration starts deferred matching. A result that arrives before the listener is ready is buffered rather than dropped.
Installation identity
The SDK creates one cryptographically random UUID in app-scoped storage. It is:
- Generated automatically.
- Scoped to one installed app.
- Reused for match, link resolution, event, and client-link operations.
- Removed when the app is uninstalled.
- An attribution identity, not proof that a device is genuine.
Your app never needs to read, set, or transmit it.
First-open behavior
- Matching runs for a genuine first launch.
- A definitive attributed or organic result resolves the installation.
- A repeated call returns the original attribution and does not reassign it.
- A transport failure can retry later within a bounded attempt policy.
- A match miss is a normal result, not an SDK error.
- Reinstalling creates a new first-launch opportunity.
Idempotency
The SDK generates stable identities for:
- A first-open match attempt.
- One warm link invocation.
- A client-created link request.
- Every queued event.
Transport retries reuse the original identity. Ferry can safely receive the same delivery more than once without creating duplicate analytics or purchases.
Event delivery
Supported events are limited to login, signup, and purchase. The SDK batches them and preserves accepted and rejected results separately.
The optional customer ID and product ID are opaque application identifiers. Production diagnostics redact these values along with keys, click IDs, installation IDs, transaction IDs, URLs, and complete payloads.
Failure behavior
Normal background SDK work degrades safely:
- Link or match failure produces no link.
- A broken or unavailable native bridge does not crash a Flutter or React Native app.
- Authentication decisions are not retried indefinitely.
- Temporary transport and server failures use bounded retry and backoff.
Client link creation is the deliberate exception. It reports a typed failure because the caller is waiting for a shareable result.
Debug logging
Native SDKs provide opt-in debug logging for integration work. Logs describe lifecycle decisions and safe request metadata while redacting credentials, identifiers, full URLs, bodies, and payloads.
Disable debug logging in production unless Ferry support asks for a short, controlled diagnostic capture.