# Migrate from AppsFlyer

> Move your existing AppsFlyer OneLink subdomain and links to Grovs without breaking old links.

Source: https://docs.grovs.io/docs/migration-guides/appsflyer

When someone opens an old OneLink, Grovs looks it up with your AppsFlyer credentials, recreates it as a Grovs link and redirects to your branded URL. After that first click, Grovs serves it directly.

This moves existing links only. To create **new** links and capture attribution through Grovs, also add the [Grovs SDK](https://docs.grovs.io/docs/sdk).

## How it works

```mermaid
flowchart TD
  A[Old OneLink opened]:::evt --> C{Cached?}:::dec
  C -->|No| D[Look up via AppsFlyer API]:::proc --> E[Create and cache link]:::proc --> R[301 to branded link]:::done
  C -->|Yes| R
```

Only the first visitor to an old link triggers the lookup. Later visits come from the cache, with no call to AppsFlyer.

## Before you start

- **An active paid subscription.** Without one, the dashboard prompts you to upgrade under **Settings → Billing**.
- **A custom AppsFlyer subdomain you control**, such as `links.acme.com`, with access to its DNS. Links on AppsFlyer's shared `*.onelink.me` domain **can't** be migrated: Grovs can only take over a hostname you control.
- **AppsFlyer OneLink data API access.** The lookup uses this API, a paid AppsFlyer entitlement. Without it, the API rejects the token. Check your AppsFlyer plan first.
- **Your OneLink ID and API token.** See [Finding your AppsFlyer credentials](#finding-your-appsflyer-credentials).
- **An updated app build, shipped before you flip DNS.**

> **Warning:** **Ship the new build before you flip DNS.** Grovs serves its own Apple App Site Association and Android assetlinks on the migrated host, replacing AppsFlyer's. If DNS moves before your app trusts the host, links open the browser instead of your app.

## Migrate your AppsFlyer hostname

### 1. Open Domain settings

Go to **Links → Link Settings → Domain** and click **Migrate from another platform**.

### 2. Confirm the pre-flight checklist

If your iOS or Android SDK is integrated, confirm each item before you can continue:

- **iOS:** `applinks:old.acme.com` is in your Associated Domains entitlement, and the build is on the App Store.
- **Android:** your `assetlinks.json` setup has the SHA-256 cert fingerprint, and the build is shipped.
- Your users have had time to update.

### 3. Choose AppsFlyer and enter your credentials

Select **AppsFlyer** and enter:

- **OneLink ID:** for example `abc123`. Grovs uses it to match incoming legacy links.
- **API token:** the V2.0 token Grovs uses to read the original link details.

### 4. Enter the old hostname

Enter the subdomain you're moving, for example `old.acme.com`. Grovs shows where its DNS points today. Submit it **before** changing DNS: Grovs provisions SSL first, and traffic only moves once DNS points at Grovs.

### 5. Complete the DNS checklist

Add each record at your DNS provider as it appears:

1. **Hostname ownership verified:** the ownership `TXT` record, if shown.
2. **SSL certificate issued:** the SSL validation `TXT` record(s). If an `_acme-challenge` record exists, replace its value or add another with the same name.
3. **CNAME pointing to Grovs:** the `CNAME`, once SSL is active.

On Cloudflare, set the CNAME to **DNS only** (gray cloud), not **Proxied** (orange). A proxied record blocks the certificate and stops links resolving.

Status refreshes as DNS updates. Click **Recheck** to poll sooner. SSL takes a few minutes to a few hours, and Grovs retries for up to 72 hours. If it doesn't issue, check the TXT record and start over to re-create the challenge.

### 6. Test credentials and flip DNS

Click **Test** to confirm Grovs can reach AppsFlyer with your credentials:

| Result                          | Action                                                                                    |
| ------------------------------- | ----------------------------------------------------------------------------------------- |
| **Credentials OK**              | Ready.                                                                                    |
| **Credentials invalid**         | Rotate them in **Settings → Migration** before flipping DNS, or old links stop resolving. |
| **Rate limited or unreachable** | AppsFlyer is temporarily unavailable. Try again shortly.                                  |

Once SSL is active and the test passes, point the old hostname's **CNAME** at Grovs. Traffic moves as DNS resolvers refresh.

## Finding your AppsFlyer credentials

- **OneLink ID:** in your OneLink template configuration.
- **API token:** open your account menu, then **Security Center → Manage your AppsFlyer API tokens** (older dashboards: **Settings → API tokens**). Copy the **V2.0** token.

## Managing and removing

When migration is active, **Links → Link Settings → Domain** shows AppsFlyer, the migrated hostname, and a green **Active** badge with the last verification time.

- **Rotate credentials:** if your token changes, use **Rotate migration credentials** in **Settings → Migration**. Grovs verifies the new credentials with AppsFlyer before saving.
- **Remove migration:** click **Remove migration** and type the hostname to confirm. This removes the migration source and the legacy hostname from Grovs.

> **Warning:** Repoint or retire the hostname's DNS before removing the migration. If DNS still points at Grovs, old links stop resolving. Removal also clears cached mappings: recreated links keep working, but if you re-onboard, each old slug hits AppsFlyer again on first click.

## Lifecycle and billing

If your subscription lapses, Grovs tears down the migrated hostname and clears the cached mappings. Recovery means re-onboarding with fresh credentials. Keep billing active for as long as you rely on migration.
