crisp docs
Blog Open app →
FDL Migration / SDK Guide

Migrating from Firebase Dynamic Links

Firebase Dynamic Links (FDL) shut down on August 25, 2025. Crisp is a drop-in resolver with the same link shape, deferred deep-link support, and one SDK call to swap. This guide takes you from a Firebase project to fully migrated in about 15 minutes.

Before you start: export your existing links from the Firebase console (Dynamic Links → ⋯ → Export). You'll upload that CSV in step 2. Your page.link domain keeps working during the cutover.

1. Install the SDK

Add the crisp SDK to your project. React Native and Flutter ship first (thin clients — hashing is server-side); native iOS and Android follow the same surface.

terminalcopy
npm install @crisp-to/react-native @react-native-async-storage/async-storage

2. Map your domain & import

In the crisp dashboard, open Deep links → Firebase import, add your existing page.link domain, and upload the CSV you exported. Crisp remaps every short suffix, parameter, and fallback automatically.

3. Swap the resolver call

Replace your getDynamicLink / handleUniversalLink handler with the crisp deferred-link handler. One callback covers both live links and post-install deferred matches, so your routing logic stays.

App.tsxTypeScript
// Before — Firebase Dynamic Links
// dynamicLinks().onLink(link => { ... })

import { CrispSDK } from "@crisp-to/react-native";

CrispSDK.initialize({ apiKey: "sdk_live_…", appId: "app_…" });
CrispSDK.onDeferredLink((link) => {
  router.navigate(link.shortCode, link.params);  // fires for live AND deferred
});

4. Deferred deep links

When a user taps a link without the app installed, crisp preserves the destination across the App Store / Play Store install. On first launch the SDK matches the install automatically — your onDeferredLink handler fires with link.deferred === true and the original params. No extra call needed.

Parameter reference

Every FDL query parameter maps to a crisp field. The import does this automatically; the table is for links you build by hand.

FDL param
Crisp field
Purpose

REST API

Everything the dashboard does — shorten, restyle, re-point — is available over HTTPS at api.crisp.to. Create a workspace key in Dashboard → API keys (it's shown once) and send it as a Bearer token. Keys work on every plan; plan limits apply to API calls exactly as they do in the dashboard.

authenticationcurl
curl https://api.crisp.to/v1/dashboard/workspaces/me \
  -H "Authorization: Bearer wk_live_…"

Responses use one envelope: {"data": …} on success, {"error": {"code", "message"}} otherwise. Codes you'll see: invalid_key (401), not_found (404), validation_failed (400/409), plan_limit (402), rate_limited (429).

Create a link — optional short_code (unique per domain), up to 10 tags, and an expires_at ISO timestamp (the link answers 410 after it):

POST /v1/dashboard/linkscurl
curl -X POST https://api.crisp.to/v1/dashboard/links \
  -H "Authorization: Bearer wk_live_…" -H "Content-Type: application/json" \
  -d '{"type":"short","destination_url":"https://example.com/sale",
       "short_code":"sale","tags":["summer","email"]}'

// 201 → {"data":{"link":{…},"url":"https://crisp.to/sale"}}

List and search with GET /v1/dashboard/links?type=short&q=…&tag=…, edit with PATCH /v1/dashboard/links/{id} (changing destination_url re-points the live short URL immediately), delete with DELETE, and export everything as CSV from GET /v1/dashboard/links/export. Free plans create 50 links per calendar month — a plan_limit error (402) tells you when you've hit it.

QR codes API

A QR code wraps its own short link, so every code is dynamic: re-point the destination any time and existing prints keep working. Scans are the wrapped link's clicks.

POST /v1/dashboard/qrcurl
curl -X POST https://api.crisp.to/v1/dashboard/qr \
  -H "Authorization: Bearer wk_live_…" -H "Content-Type: application/json" \
  -d '{"name":"Menu QR","destination_url":"https://cafe.example/menu",
       "fg_color":"#1A1712","bg_color":"#FBF4E9"}'

// 201 → {"data":{"qr":{…},"url":"https://crisp.to/x7Kq"}}

Colors (fg_color, bg_color, frame_color) work on every plan. The style object — module shapes (dots: square/dots/rounded), corner styles, error-correction level, and logo_url — is Creator and up (402 otherwise). GET /v1/dashboard/qr lists codes with scan counts; PATCH /v1/dashboard/qr/{id} restyles or re-points; DELETE removes the code and its wrapped link.

The machine-readable OpenAPI spec ships in the repo (apps/api-crisp-to/openapi.yaml) and covers the full surface, including bio pages and billing.

← Previous
Parameter reference
Next →
Short links API

How can we help?

Still stuck?

Design partners get direct support from the team that built the resolver. Median first reply: 2 hours.

Email support Join the community