React Native API Reference
The complete TypeScript API reference for the WarpLink React Native SDK: initialization, deep link events, and attribution.
WarpLink
The main entry point. Exported from @warplink/react-native.
import { WarpLink } from '@warplink/react-native';
configure(options)
configure(options: WarpLinkConfig): Promise<void>
Initialize the SDK. The key format is validated synchronously; the returned promise resolves after native configuration completes, including the automatic cold-start and deferred deep link dispatch.
| Parameter | Type | Description |
|---|---|---|
options | WarpLinkConfig | Configuration with your SDK key, the onLink callback, and optional settings. |
When onLink is set, configure() wires getInitialDeepLink (cold start), onDeepLink (warm start), and checkDeferredDeepLink (deferred) into that single callback. Disambiguate the deferred case with isDeferred. Set automaticDeepLinks or automaticDeferredDeepLinks to false to disable either piece.
Does not throw. A malformed SDK key is reported through your onLink callback as an { error } event with code E_INVALID_API_KEY_FORMAT, and always logs a warning. The SDK stays unconfigured. iOS and Android behave the same way.
handleDeepLink(url)
handleDeepLink(url: string): Promise<WarpLinkDeepLink | null>
Resolve a deep link URL to its link data.
Errors: E_NOT_CONFIGURED, E_INVALID_URL, E_LINK_NOT_FOUND, E_PASSWORD_REQUIRED, E_NETWORK_ERROR, E_SERVER_ERROR, E_INVALID_API_KEY, E_DECODING_ERROR
checkDeferredDeepLink()
checkDeferredDeepLink(): Promise<WarpLinkDeepLink | null>
Check for a deferred deep link on first launch. Returns null if no match found. On subsequent launches, returns the cached result.
"First launch" means the first launch of the current install. A reinstall is a new install and runs the check again, with is_reinstall set on the request. See App Reinstall.
Errors: E_NOT_CONFIGURED, E_NETWORK_ERROR, E_SERVER_ERROR, E_INVALID_API_KEY, E_DECODING_ERROR
getAttributionResult()
getAttributionResult(): Promise<AttributionResult | null>
Get install attribution data. Returns null if no attribution match found.
isConfigured()
isConfigured(): Promise<boolean>
Check whether the SDK has been configured.
sdkVersion()
sdkVersion(): Promise<string>
Returns the version of the native WarpLink SDK the app is actually running, not the @warplink/react-native package version. This distinction matters because the package bundles the native WarpLink SDK. Calling sdkVersion() asks the native side directly, so you always see the version your app runs.
console.log(await WarpLink.sdkVersion()); // "1.1.1"
isAttributionComplete()
isAttributionComplete(): Promise<boolean>
Whether the deferred attribution check has definitively completed for the current install. Scoped to one install: it reads false again after the app is deleted and reinstalled, or restored from a device backup, because a reinstall is attributed again from scratch. The automatic dispatch inside configure() already reads this before deciding whether to re-fire the deferred check, so a normal integration built on the opt-out model never has to call it directly. It is useful for diagnostics, or for a host that drives checkDeferredDeepLink() manually with automaticDeferredDeepLinks: false.
onDeepLink(listener)
onDeepLink(listener: DeepLinkListener): () => void
Register a listener for warm-start deep link events. Returns an unsubscribe function.
getInitialDeepLink()
getInitialDeepLink(): Promise<WarpLinkDeepLink | null>
Get the deep link that launched the app (cold start). Returns null if not launched via a link.
Types
WarpLinkConfig
interface WarpLinkConfig {
apiKey: string;
apiEndpoint?: string; // Default: "https://api.warplink.app/v1"
debugLogging?: boolean; // Default: false
onLink?: (event: { deepLink?: WarpLinkDeepLink; error?: WarpLinkError }) => void; // Cold/warm/deferred, or an error
automaticDeepLinks?: boolean; // Default: true
automaticDeferredDeepLinks?: boolean; // Default: true
linkDomains?: string[]; // Default: [] (custom domains you serve links from)
matchWindowHours?: number; // @deprecated Server-side only, no effect
}
matchWindowHours is accepted for backward compatibility but has no effect: the match window is set per link in the dashboard.
linkDomains
Hosts the SDK should treat as yours, in addition to aplnk.to. configure() forwards the list to the native SDKs, which own the domain set and the normalization (trimmed, lowercased, a full URL reduced to its host). Declaring a custom domain here is what lets a link on it resolve on the first launch, before the SDK has reached the server. The same domains can be declared natively instead: see iOS and Android.
WarpLinkDeepLink
interface WarpLinkDeepLink {
linkId: string;
destination: string;
deepLinkUrl: string | null;
customParams: Record<string, unknown>;
isDeferred: boolean;
matchType: 'deterministic' | 'probabilistic' | null;
matchConfidence: number | null;
matchGuaranteed: boolean;
}
AttributionResult
interface AttributionResult {
linkId: string;
matchType: 'deterministic' | 'probabilistic';
matchConfidence: number;
matchGuaranteed: boolean;
isDeferred: boolean;
}
DeepLinkEvent
Discriminated union: exactly one of deepLink or error is present.
type DeepLinkEvent =
| { deepLink: WarpLinkDeepLink; error?: undefined }
| { deepLink?: undefined; error: WarpLinkError };
DeepLinkListener
type DeepLinkListener = (event: DeepLinkEvent) => void;
Error Types
WarpLinkError
class WarpLinkError extends Error {
readonly code: ErrorCode;
constructor(code: ErrorCode, message: string);
}
ErrorCodes
const ErrorCodes = {
E_NOT_CONFIGURED: 'E_NOT_CONFIGURED',
E_INVALID_API_KEY_FORMAT: 'E_INVALID_API_KEY_FORMAT',
E_INVALID_API_KEY: 'E_INVALID_API_KEY',
E_NETWORK_ERROR: 'E_NETWORK_ERROR',
E_SERVER_ERROR: 'E_SERVER_ERROR',
E_INVALID_URL: 'E_INVALID_URL',
E_LINK_NOT_FOUND: 'E_LINK_NOT_FOUND',
E_PASSWORD_REQUIRED: 'E_PASSWORD_REQUIRED',
E_DECODING_ERROR: 'E_DECODING_ERROR',
} as const;
| Code | Description |
|---|---|
E_NOT_CONFIGURED | SDK not initialized. |
E_INVALID_API_KEY_FORMAT | Key format invalid. |
E_INVALID_API_KEY | Key rejected by server. |
E_NETWORK_ERROR | Network unreachable or timeout. |
E_SERVER_ERROR | Server returned 5xx. |
E_INVALID_URL | Not a recognized WarpLink domain. |
E_LINK_NOT_FOUND | Link not found or inactive. |
E_PASSWORD_REQUIRED | Link is password protected, so it resolves to no destination and no platform URLs. |
E_DECODING_ERROR | Malformed server response. |
Native Bridge
@warplink/react-native is a classic native-module bridge (NativeModules + a single NativeEventEmitter channel, onWarpLinkDeepLink), not a TurboModule authored from scratch. React Native's interop layer runs classic modules unmodified under both the classic and New Architecture (Fabric/TurboModules), so every method and type on this page behaves identically regardless of which architecture your app runs.
Two properties of the bridge shape are worth knowing when debugging:
- Every promise-returning method here (
handleDeepLink,checkDeferredDeepLink,getAttributionResult,isConfigured,sdkVersion,isAttributionComplete) makes one native call and resolves or rejects from its answer. None of them poll. onDeepLink()and the automaticonLinksink both read from the same underlying native event stream; the TypeScript layer fans one native event out to every JavaScript subscriber rather than opening a separate native subscription per listener.
If the module is not linked (NativeModules['WarpLinkModule'] is undefined), every method on WarpLink throws synchronously with a linking error rather than rejecting a promise, since there is no native module to make the call against. See Deep Links: Troubleshooting for the common causes.
Platform Requirements
{
"peerDependencies": {
"react": ">=18.0.0",
"react-native": ">=0.75.0"
}
}
The native side has its own floor: iOS 15.0 (set in warplink-react-native.podspec) and Android API 26 / Android 8.0 (minSdk in the module's android/build.gradle.kts), matching the standalone iOS and Android SDKs exactly, since this package embeds them rather than reimplementing anything. Node.js 18+ is required to build the package itself, not to run the resulting app.
TypeScript Types Exported
Every type in this reference is exported from the package root, not from an internal path:
import {
WarpLink,
WarpLinkError,
ErrorCodes,
type ErrorCode,
type WarpLinkConfig,
type WarpLinkDeepLink,
type AttributionResult,
type DeepLinkEvent,
type DeepLinkListener,
} from '@warplink/react-native';
Importing from an internal path such as @warplink/react-native/src/WarpLink is unsupported and will break on a future release; the package's main/module/types fields all resolve through the root entry point.
Expo
The SDK works in an Expo development build (npx expo prebuild or EAS Build). Add the iOS host hook (WarpLinkModule.handleIncomingURL, see Deep Links) to the generated AppDelegate/SceneDelegate, or reinsert it on every prebuild with a small withAppDelegate config plugin. Associated Domains and the Android intent filter both have app.json equivalents and need no manual native editing.
Troubleshooting
customParams values come back as unknown and TypeScript complains. This is deliberate. Custom parameters are the query parameters of the link's destination URL, returned as a JSON object, so the type is Record<string, unknown> rather than a link-specific shape the SDK cannot know ahead of time. Narrow with a type assertion or a runtime check at the call site: link.customParams['product_id'] as string | undefined.
sdkVersion() reports a different version than the npm package. The native SDK version is versioned separately and reflects the SDK your app runs.
FAQ
Does configure() need to be awaited before calling other methods? Not strictly. configure()'s promise resolves once native configuration, cold-start dispatch, and (when a sink is present) the deferred check have all settled, but handleDeepLink() and the other methods each make their own native call and will queue behind an in-progress native configuration rather than fail. Awaiting configure() is still the simplest way to know setup fully finished.
How do I use WarpLink from React function components? The package exports a single module-level WarpLink object with promise-based methods and an event subscription (onDeepLink), the same shape on every platform this SDK supports. Wrap it in your own hook if your codebase prefers that pattern; there is nothing React-specific in the underlying calls that a hook would add.
What TypeScript version is required? The package ships its own .d.ts files built against the react-native peer dependency's types; any TypeScript version compatible with your installed react-native and @types/react versions works. There is no WarpLink-specific TypeScript floor beyond what React Native itself requires.
Does getAttributionResult() make a network call, or read a cached value? It reads the native SDK's cached result from the deferred check that already ran; it does not trigger a new attribution request. Call checkDeferredDeepLink() if you need to force the check to run (only meaningful before it has completed for the current install).
React Native Install Attribution
How the WarpLink React Native SDK attributes installs across iOS and Android, with match types, confidence scores, and privacy controls.
Flutter SDK
Integrate the WarpLink Flutter SDK for Universal Links on iOS, App Links on Android, deferred deep links, and install attribution.