DevRoute SDK

One script tag. Instant device intelligence — eSIM support, fraud signals, network type, and smart conversion routing for every visitor.

DevRoute works entirely client-side. You add a <script> tag, call DevRoute.init(), and receive a structured result object with everything you need to route, personalize, or protect your users. No build step. No dependencies. No npm.

Just a script tag. Works on any website — vanilla HTML, React, Vue, WordPress, Webflow. If it runs JavaScript in a browser, DevRoute works.

Quick Start

Three steps to get your first device result.

1
Get your API key

Sign up at devroute.app/register. Your key is available immediately on the dashboard.

2
Add the script tag

Paste this in the <head> or just before </body> of your page.

3
Call DevRoute.init()

Pass your API key and an onResult callback. That's it.

html
<!-- Step 2: Add the SDK -->
<script src="https://devroute.app/sdk/v3/devroute.min.js"></script>

<!-- Step 3: Initialize -->
<script>
  DevRoute.init({
    apiKey: 'esim_live_YOUR_API_KEY',
    onResult: function(result) {
      console.log('Device:', result.brand, result.model);
      console.log('eSIM supported:', result.esim.esimSupported);
    }
  });
</script>

Installation

CDN (recommended)

Always points to the latest v3 release. Cached globally via Cloudflare CDN.

html
<script src="https://devroute.app/sdk/v3/devroute.min.js"></script>

Pinned version

Use a specific version if you need reproducible builds.

html
<script src="https://devroute.app/sdk/v3.0.0/devroute.min.js"></script>

The SDK is a single file with zero dependencies and no external requests beyond the DevRoute API. It works offline (returns cached data from sessionStorage on repeat calls within the same browser tab).

DevRoute.init(options)

The single entry point. Call it once per page load — usually right after the script tag. Results are cached in sessionStorage so repeat calls within the same tab return instantly without an extra API request.

javascript
DevRoute.init({
  // Required
  apiKey: 'esim_live_YOUR_API_KEY',

  // Called with the result object when detection succeeds
  onResult: function(result) {
    // result contains device, eSIM, network, and risk data
  },

  // Called if the API request fails (optional)
  onError: function(err) {
    console.warn('DevRoute error:', err.message);
  }
});

Options

Option Type Required Description
apiKey string Required Your DevRoute API key. Get it from the dashboard. Format: esim_live_...
onResult function Optional Callback invoked with the result object on success. Also called immediately with cached data if available.
onError function Optional Callback invoked if the API request fails. Receives an Error object.
apiEndpoint string Optional Override the API endpoint. Defaults to the DevRoute edge worker. Only change this if instructed by support.

Response Object

The result object passed to onResult. Available fields depend on your plan — fields from higher plans are null on lower plans.

javascript — full response shape
{
  // ── Device — Free+ ──────────────────────────────────────────────────
  id:               "sha256_device_hash",  // unique device fingerprint
  brand:            "Samsung",
  model:            "Galaxy S24",
  confidence:       0.92,            // 0.0–1.0 detection confidence
  detectionMethod:  "server-index-lookup",
  OS: {
    name:    "Android",
    version: "14"
  },
  screenResolution: "1080x2340",
  pixelRatio:       3,
  timezone:         "America/New_York",
  language:         "en-US",

  // ── eSIM & Routing — Starter+ ────────────────────────────────────────
  family:       "Galaxy S24 Series",
  GPU:          "Adreno 750",
  networkType:  "4g",       // "2g" | "3g" | "4g" | "5g" | "wifi"
  device_tier: "premium",  // "premium" | "mid" | "budget" | "unknown"
  device_hash: "sha256...", // stable fingerprint across sessions
  esim: {
    esimSupported:      true,
    dualEsim:           false,
    conversionStrategy: "guided_install",  // see Conversion Strategies below
    recommendedFlow:    "step_by_step"
  },
  intelligence: {               // see Intelligence Engine section
    decisions: {
      esim_flow:     { value: "step_by_step", reason: "Samsung device on Android 14..." },
      friction:      { value: "none",          reason: "Low risk score, trusted signals" },
      security_gate: { value: "none",          reason: "No fraud signals detected" },
      ui_mode:       { value: "streamlined",  reason: "Premium device, simplify UI" },
      priority:      { value: "high",          reason: "eSIM capable, premium segment" }
    },
    narrative: {
      headline: "Genuine Samsung user ready for guided eSIM install"
    }
  },

  // ── Network — Growth+ ────────────────────────────────────────────────
  IP:          "203.0.113.42",
  isp:         "Comcast Cable",
  vpn:         false,
  ram:         8,    // GB, from navigator.deviceMemory
  cores:       8,    // from navigator.hardwareConcurrency
  asn:         7922,
  httpProtocol: "HTTP/2",

  // ── Fraud + Geo — Enterprise+ ────────────────────────────────────────
  emulator:         false,
  bot:              false,
  risk_score:       8,      // 0–100, higher = riskier
  signal_conflicts: [],    // array of detected signal contradictions
  timezone_mismatch: false, // browser TZ ≠ IP TZ → VPN signal
  country:          "US",  // ISO 3166-1 alpha-2
  city:             "New York",
  region:           "New York",
  latitude:         40.71,
  longitude:        -74.00,
  postalCode:       "10001",
  isEUCountry:      false,
  tlsVersion:       "TLSv1.3",
  threatScore:      0       // Proxycheck.io threat score (0–100)
}

Field reference

Field Type Description Plan
idstringSHA-256 device fingerprint (stable across sessions)Free
brandstringDevice manufacturer (e.g. "Samsung", "Apple")Free
modelstringDevice model nameFree
confidencenumberDetection confidence 0.0–1.0Free
detectionMethodstringHow the device was identified (see Detection Methods below)Free
OS.namestring"iOS" / "Android" / "iPadOS"Free
OS.versionstringOS version string e.g. "17.2" or "14"Free
screenResolutionstringPhysical resolution e.g. "1179x2556"Free
pixelRationumberDevice pixel ratioFree
timezonestringIANA timezone e.g. "America/New_York"Free
languagestringBrowser language e.g. "en-US"Free
familystringDevice family / product lineStarter
GPUstringGPU renderer string from WebGLStarter
networkTypestringConnection type: "2g" / "3g" / "4g" / "5g" / "wifi"Starter
device_tierstring"premium" / "mid" / "budget" / "unknown" — based on GPU + modelStarter
device_hashstringStable device fingerprint for cross-session trackingStarter
esim.esimSupportedbooleanWhether the device supports eSIMStarter
esim.dualEsimbooleanWhether the device supports two concurrent eSIMsStarter
esim.conversionStrategystringRecommended install strategy — see Conversion StrategiesStarter
esim.recommendedFlowstringRecommended UI flow — see Conversion StrategiesStarter
intelligence.decisions.*objectFive decisions as { value, reason } — see Intelligence EngineStarter
intelligence.narrative.headlinestringOne-line summary of the sessionStarter
intelligence.profileobjectUser segment, confidence, and signalsGrowth
intelligence.authenticityobjectAuthenticity score (0–100) + verdict + signalsGrowth
intelligence.scoresobjectrisk / conversion / experience scores (0–100 each)Growth
IPstringClient IP addressGrowth
ispstringInternet service provider nameGrowth
vpnbooleanTrue if connection is from a VPN or datacenterGrowth
ramnumberDevice RAM in GB (from navigator.deviceMemory)Growth
coresnumberCPU core count (from navigator.hardwareConcurrency)Growth
emulatorbooleanTrue if device is an emulator or automation toolEnterprise
botbooleanTrue if headless browser or scraper detectedEnterprise
risk_scorenumberFraud risk score 0–100 (higher = riskier)Enterprise
signal_conflictsstring[]Detected cross-signal contradictions (empty = clean)Enterprise
timezone_mismatchbooleanBrowser timezone differs from IP timezone — VPN signalEnterprise
countrystringISO 3166-1 country code (from Cloudflare edge)Enterprise
citystringCity nameEnterprise
regionstringRegion / state nameEnterprise
latitude / longitudenumberGPS coordinates from Cloudflare edgeEnterprise
postalCodestringPostal / ZIP codeEnterprise
isEUCountrybooleanTrue if device is in an EU member countryEnterprise
tlsVersionstringTLS version used (e.g. "TLSv1.3")Enterprise
threatScorenumberIP threat score from Proxycheck.io (0–100)Enterprise

Conversion strategies

The esim.conversionStrategy field tells you how to best route the user. Use it to show the right flow without asking the user to self-identify their device.

conversionStrategyrecommendedFlowMeaningRecommended action
"direct_install""auto_install"iOS 16+ or Google Pixel — carrier tap-through availableShow "Activate eSIM" button; deep-link to carrier activation URL
"guided_install""step_by_step"Samsung or Android 12+ — OS-native eSIM wizard availableOpen step-by-step modal linking to Settings > Mobile > Add eSIM
"qr_install""scan_qr"eSIM supported, no native deep-link flowDisplay QR code with scan instructions
"manual_install""manual_setup"Low confidence detection, cannot verify deviceShow activation code entry form as fallback
"unsupported_device""show_unsupported"Device confirmed as eSIM-incapableShow upgrade prompt or physical SIM flow

Detection methods

The detectionMethod field indicates how the device was identified, which reflects detection confidence:

ValueConfidenceDescription
"server-iphone-direct"HighMatched via screen resolution + DPR matrix (iPhone/iPad)
"server-multi-signal"HighMatched via UA + resolution + DPR + OS + touch scoring
"server-index-lookup"MediumMatched via Android model code index (42,000+ codes)
"server-ua-extract"MediumExtracted from UA string with brand inference
"gpu_cpu_ram_inference"Low–MediumInferred from GPU + CPU family + RAM/screen signals

Intelligence Engine

Available on Starter and above. The engine runs five decision layers on every detection and returns structured outputs with a value and a human-readable reason.

Decisions — intelligence.decisions

Each field returns { value: string, reason: string }. Use value to drive logic and reason to display context or log decisions.

javascript
var d = result.intelligence.decisions;

// Always use .value to drive your logic
console.log(d.esim_flow.value);   // "auto_install"
console.log(d.esim_flow.reason);  // "iOS 17 with confirmed eSIM — use Quick Transfer"

console.log(d.friction.value);    // "none" | "soft" | "hard"
console.log(d.security_gate.value); // "none" | "review" | "block"
console.log(d.ui_mode.value);     // "streamlined" | "standard" | "cautious"
console.log(d.priority.value);    // "high" | "medium" | "low"
DecisionValuesDescription
esim_flowauto_install / step_by_step / scan_qr / manual_setup / show_unsupportedWhich eSIM installation flow to trigger
frictionnone / soft / hardWhether to add verification steps (soft = captcha, hard = SMS OTP)
security_gatenone / review / blockWhether to allow, flag for review, or block the session
ui_modestreamlined / standard / cautiousHow much to simplify or guard your UI for this session
priorityhigh / medium / lowConversion priority — use for A/B testing and upsell targeting

Profile & scores — Growth

Growth plan adds user segment classification and three conversion scores:

javascript
var intel = result.intelligence;

// User segment
intel.profile.segment;     // "genuine_user" | "corporate_user" | "privacy_user"
                            // | "traveler" | "developer" | "fraudulent_actor"
                            // | "automated_actor" | "tor_user" | "unclassified"
intel.profile.confidence;  // 0.0–1.0 segment confidence
intel.profile.signals;    // ["esim_capable", "residential_isp", ...]

// Authenticity
intel.authenticity.score;   // 0–100 (higher = more authentic)
intel.authenticity.verdict; // "authentic" | "suspicious" | "likely_bot"

// Scores (0–100)
intel.scores.risk;        // fraud risk (lower = safer)
intel.scores.conversion;  // likelihood to convert (higher = better)
intel.scores.experience;  // UX quality score — use to gate premium features

Error Handling

If the API call fails — network timeout, invalid API key, or plan limit reached — the onError callback is called. The SDK never throws; all errors are caught internally.

javascript
DevRoute.init({
  apiKey: 'esim_live_YOUR_KEY',
  onResult: function(result) {
    // happy path
  },
  onError: function(err) {
    // err.message — human-readable error
    // Common: "HTTP 401" (bad key), "HTTP 429" (limit reached), network errors
    console.warn('[DevRoute]', err.message);
  }
});
HTTP StatusMeaningWhat to do
401Invalid API keyCheck your key in the dashboard. Ensure the request comes from a whitelisted domain.
429Monthly detection limit reachedUpgrade your plan or wait for the next billing cycle.
500Detection failedRare. Contact support if it persists.

Domain locking. API keys can be restricted to specific domains. If you see a 401 on a new domain, add it to the allowed domains list in API Keys settings.

Example — eSIM Routing

Show the right onboarding flow based on real device eSIM support.

javascript — starter plan
DevRoute.init({
  apiKey: 'esim_live_YOUR_KEY',
  onResult: function(result) {
    var flow = result.esim.conversionStrategy;

    if (flow === 'direct_install') {
      // iOS 16+ / Pixel — tap-through carrier activation, no QR needed
      showActivateButton(carrierDeepLinkUrl);

    } else if (flow === 'guided_install') {
      // Samsung / Android 12+ — OS-native Settings wizard
      showGuidedModal(result.brand, result.OS.version);

    } else if (flow === 'qr_install') {
      // eSIM supported, show QR code for profile download
      showQRCode();

    } else if (flow === 'manual_install') {
      // Low-confidence detection — show activation code entry
      showActivationCodeForm();

    } else if (flow === 'unsupported_device') {
      // Device can't use eSIM — offer physical SIM or upgrade
      showPhysicalSimFallback();
    }

    // Optional: use intelligence decisions for UX fine-tuning
    var d = result.intelligence?.decisions;
    if (d?.ui_mode?.value === 'streamlined') collapseSecondaryOptions();
    if (d?.priority?.value === 'high') showPremiumPlanBanner();
  }
});

Example — Fraud Detection

Block or flag sessions with high risk signals before checkout. Use intelligence.decisions (Starter+) for decision logic, and risk_score / bot (Enterprise+) for numerical thresholds.

javascript — starter plan (decisions)
DevRoute.init({
  apiKey: 'esim_live_YOUR_KEY',
  onResult: function(result) {
    var gate     = result.intelligence?.decisions?.security_gate?.value;
    var friction = result.intelligence?.decisions?.friction?.value;

    if (gate === 'block') {
      blockSession();          // high-confidence fraud
    } else if (gate === 'review' || friction === 'hard') {
      showSmsVerification();   // suspicious — step-up auth
    } else if (friction === 'soft') {
      showCaptcha();           // mild friction only
    } else {
      enableCheckout();        // clean session
    }
  }
});
javascript — enterprise plan (risk_score + bot)
DevRoute.init({
  apiKey: 'esim_live_YOUR_KEY',
  onResult: function(result) {
    var riskScore  = result.risk_score;   // 0–100
    var isBot      = result.bot;
    var isVpn      = result.vpn;           // Growth+
    var conflicts  = result.signal_conflicts; // array of contradiction strings

    if (isBot || riskScore > 80) {
      blockSession();
    } else if (isVpn || riskScore > 50 || conflicts.length > 1) {
      triggerStepUpVerification();
    } else {
      enableCheckout();
    }
  }
});

Example — Geo Pricing

Display localized prices based on country without a separate geolocation API call.

javascript — enterprise plan
var REGIONAL_PRICES = {
  'US': { amount: '$4.99',  currency: 'USD' },
  'GB': { amount: '£3.99',  currency: 'GBP' },
  'DE': { amount: '€4.49',  currency: 'EUR' },
  'IN': { amount: '₹99',    currency: 'INR' },
};

DevRoute.init({
  apiKey: 'esim_live_YOUR_KEY',
  onResult: function(result) {
    var country = result.country;
    var price   = REGIONAL_PRICES[country] || REGIONAL_PRICES['US'];
    document.getElementById('price-display').textContent = price.amount;
  }
});

Plan Limits

PlanMonthly detectionsPrice
Free1,000$0
Starter25,000$39/mo
Growth100,000$129/mo
Enterprise500,000$399/mo

Limits reset on the 1st of each month. When a limit is reached, the API returns HTTP 429 and detection stops until the next cycle or you upgrade.

See full plan comparison →

Fields by Plan

Fields from higher plans return null on lower plans — no errors, just null values.

PlanAvailable fields
Free id, brand, model, confidence, detectionMethod, OS, screenResolution, pixelRatio, timezone, language
Starter Free + family, GPU, networkType, device_tier, device_hash, esim.*, intelligence.decisions, intelligence.narrative.headline
Growth Starter + IP, isp, vpn, ram, cores, asn, httpProtocol, intelligence.profile, intelligence.authenticity, intelligence.scores
Enterprise Growth + emulator, bot, risk_score, signal_conflicts, timezone_mismatch, country, city, region, latitude, longitude, postalCode, isEUCountry, tlsVersion, threatScore