Power your network with the industry’s leading data platform for knowing where your vehicles were, are, and will be next























Best-in-class vehicle predictions that leverage real-time disruption information, paired with optional rider alerts
Best-in-class vehicle predictions
Historical trends that support smart decision-making, build consensus, and improve the rider experience across the agency
Historical trends that support smart decision-making
Dynamic real-time fleet visibility and management that allow everyone and everything to know what’s happening in the network
Dynamic real-time fleet visibility and management
Real-time data quality monitoring across existing systems, plus APIs and open data standards, drive permissionless innovation
Real-time data quality monitoring across existing systems, APIs and open data standards
Swiftly is improving public transit at agencies large and small around the globe.




Transform the rider experience with best-in-class real-time passenger information and industry-defining prediction algorithms.
Boost on-time performance and headway adherence with real-time adjustments for your operators and historical insights for operations staff.


Plan and evaluate service changes using intuitive data visualizations of billions of historical data points.
Optimize your schedule using actual run-times, vehicle speeds, and dwell times.


No matter who is calling and when, your customer service team can instantly answer any question a rider has about your system.
See how Swiftly can improve service reliability, passenger information, and operational efficiency at your agency with an in-depth demo.
is fine). */ (function () { if (!window.MktoForms2) return; // ----------------------------- // CONFIG // ----------------------------- const COUNTRY_FIELD_NAME = "geoLocationviaIPValue"; // <-- change if your hidden field uses a different name const COUNTRY_CACHE_KEY = "ms_mkto_country_v1"; const COUNTRY_CACHE_TTL_MS = 1000 * 60 * 60 * 24 * 7; // 7 days // If the hidden field already has a value, should we overwrite it? // Recommended: false (don’t override existing values) const OVERWRITE_EXISTING_COUNTRY_VALUE = false; // ----------------------------- // Tiny helpers: cookie fallback // ----------------------------- function setCookie(name, value, ttlMs) { try { const expires = new Date(Date.now() + ttlMs).toUTCString(); const secure = location.protocol === "https:" ? "; Secure" : ""; document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; expires=${expires}; path=/; SameSite=Lax${secure}`; } catch (_) {} } function getCookie(name) { try { const n = encodeURIComponent(name) + "="; const parts = document.cookie.split("; "); for (const p of parts) { if (p.indexOf(n) === 0) return decodeURIComponent(p.slice(n.length)); } } catch (_) {} return null; } function deleteCookie(name) { try { const secure = location.protocol === "https:" ? "; Secure" : ""; document.cookie = `${encodeURIComponent(name)}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; SameSite=Lax${secure}`; } catch (_) {} } // ----------------------------- // Country cache (LS -> cookie) // ----------------------------- function readCountryCache() { try { const raw = localStorage.getItem(COUNTRY_CACHE_KEY); if (raw) { const parsed = JSON.parse(raw); if (parsed && parsed.country && parsed.exp && Date.now() <= parsed.exp) { return String(parsed.country).toUpperCase(); } localStorage.removeItem(COUNTRY_CACHE_KEY); } } catch (_) {} const c = getCookie(COUNTRY_CACHE_KEY); if (!c) return null; // cookie stores "CC|exp" const parts = String(c).split("|"); if (parts.length !== 2) return null; const country = parts[0]; const exp = Number(parts[1]); if (!country || !Number.isFinite(exp) || Date.now() > exp) { deleteCookie(COUNTRY_CACHE_KEY); return null; } return String(country).toUpperCase(); } function writeCountryCache(country) { const cc = String(country || "").toUpperCase(); if (!cc) return; const exp = Date.now() + COUNTRY_CACHE_TTL_MS; try { localStorage.setItem(COUNTRY_CACHE_KEY, JSON.stringify({ country: cc, exp })); return; } catch (_) {} setCookie(COUNTRY_CACHE_KEY, `${cc}|${exp}`, COUNTRY_CACHE_TTL_MS); } // ----------------------------- // Fetch country (two-digit code) // ----------------------------- async function fetchCountryCode() { // Primary try { const res = await fetch("https://api.country.is/", { cache: "no-store" }); const data = await res.json(); if (data && data.country) return String(data.country).toUpperCase(); } catch (_) {} // Fallback try { const res = await fetch("https://ipwho.is/", { cache: "no-store" }); const data = await res.json(); if (data && data.success && data.country_code) { return String(data.country_code).toUpperCase(); } } catch (_) {} return null; } // In-flight singleton so multiple forms don’t trigger multiple fetches let countryPromise = null; async function getCountryCodeOnce() { const cached = readCountryCache(); if (cached) return cached; if (!countryPromise) { countryPromise = (async () => { const cc = await fetchCountryCode(); if (cc) writeCountryCache(cc); return cc; })(); } return countryPromise; } // ----------------------------- // Apply country to a specific form // ----------------------------- function setCountryOnForm(form) { if (!form || typeof form.getFormElem !== "function") return; const formEl = form.getFormElem()[0]; if (!formEl) return; // If the field doesn't exist on this form, no-op const input = formEl.querySelector( `input[name="${CSS.escape(COUNTRY_FIELD_NAME)}"]` ); if (!input) return; // Respect existing value unless you want overwrite const existing = (input.value || "").trim(); if (!OVERWRITE_EXISTING_COUNTRY_VALUE && existing) return; // Fetch + set getCountryCodeOnce().then((cc) => { if (!cc) return; // Set via Marketo API (best) try { form.setValues({ [COUNTRY_FIELD_NAME]: cc }); } catch (_) {} // Also set DOM value for redundancy input.value = cc; input.dispatchEvent(new Event("input", { bubbles: true })); input.dispatchEvent(new Event("change", { bubbles: true })); }); } // ----------------------------- // Global hook: runs for every form // ----------------------------- MktoForms2.whenReady(function (form) { // Country -> hidden field setCountryOnForm(form); }); })();