Help & API

How to use every screen, the support PIN, and the Scale REST API.

How to use ForeverLink

ForeverLink is a numbered inventory of links you can reprint-proof. You generate IDs (1…N), print the public ForeverLink URL on a QR, NFC tag or sticker, and change the HTTPS destination later — from the panel, CSV, the Scale API, or the support chat.

Public URL of every ID:

https://foreverlink.app/r/{your-org}/{number}

Example: https://foreverlink.app/r/acme/42

The public URL name never changes (so printed pieces keep working). Only the destination changes.

---

1. Create your account

  1. Open Register or pick a plan on Pricing.
  2. Choose Starter ($19/mo, 500 IDs), Growth ($49/mo, 5,000) or Scale ($99/mo, 25,000 + API). White Label is a $999 one-time license.
  3. Pick an organization name. The public URL name becomes part of every printed URL. You cannot rename it later.
  4. Confirm email / password. 2FA (Google Authenticator / Authy) is optional — enable it later in Settings.
  5. Complete Paddle checkout (card required). You get a 15-day trial. Cancel before it ends and you are not charged.
  6. Until billing is trialing or active, public QR codes will not redirect.

---

2. First 15 minutes

  1. Sign in at /login → you land on Inventory.
  2. Open Generate range and create IDs 1 to 100 (or whatever you will print).
  3. Open Assign range and set a destination for 1–20, plus a label like shop-front.
  4. Open ID #1 and download the SVG QR. That QR encodes the ForeverLink URL, not the final website.
  5. Scan it. You should land on the destination. If you see “not configured”, the ID has no https destination or it is inactive.
  6. Change the destination on #1 and scan again — same QR, new page.

---

3. Inventory

The inventory is the list of every stock ID in the active organization.

  • Search by number, label, destination or notes.
  • Filter: all / never clicked / no destination / active / inactive.
  • Sort by number or clicks.
  • Each row is one public URL: /r/{org}/{number}.

Click a row to edit that ID.

---

4. New ID

New ID creates a single stock number.

  1. Leave the number empty to use the next free ID, or type a specific number that does not exist yet.
  2. Optional: destination (https://…), label, notes, status (active / inactive).
  3. Save. The ID counts against your plan max_links limit.

Use this for a one-off sticker. Use Generate range for a print run.

---

5. Generate range

Creates empty IDs in an inclusive range (example: 1 to 1000).

  • Existing numbers are skipped (safe to re-run).
  • New IDs start active with no destination.
  • The range cannot push you past the plan limit.

Do this before you send files to the printer.

---

6. Assign range

Writes the same destination, label and status across a from–to range that already exists.

Typical uses:

  • Point IDs 1–50 at this month’s menu.
  • Relabel a client batch when they leave (old-client → new URL).
  • Turn a campaign off: set status inactive on that range.

Destinations must be http:// or https:// with a host, max 2048 characters.

---

Open the ID from inventory.

You can change:

FieldMeaning
DestinationWhere the scan goes. Empty = public page says “not configured”.
LabelBatch / client / location. Used to search and bulk-deactivate.
NotesInternal only. Never shown to the person who scans.
Statusactive redirects. inactive does not.

The page also shows:

  • Total clicks and last click
  • Last 14 days
  • Change history (who, when, before → after)

Download the production QR (SVG) here. Always print this QR, never a QR of the final Google / menu URL.

---

8. Import and export CSV

Export downloads the current inventory (optional label filter).

Import upserts rows. Typical columns: number, target_url, label, notes, status.

  • Invalid URLs are rejected.
  • Import writes a revision on each change (source = import).
  • Stay under max_links.

Use Excel or your print ERP, then import.

---

9. Clicks and history

Every successful public redirect increments click_count and a daily counter.

Inventory alerts:

  • Active IDs with no destination (printed but dead)
  • IDs that were never scanned

History records destination, label, status and notes changes, with source: manual, import, range, API or chat.

---

10. Team

Roles:

RoleCan
OwnerEverything, including billing and PIN / API keys
AdminSettings, team, PIN, API keys, inventory
OperatorAssign destinations, generate/assign ranges, import

Add a member under Team with a temporary password (min. 12 characters). They must sign in and can enable 2FA.

If you belong to more than one organization, switch it in Settings.

---

11. Settings

  • Rename the organization display name (not the public URL name).
  • Enable 2FA.
  • Set the Support PIN (6–8 digits). WhatsApp / Telegram / web chat will ask for the public URL name or email + this PIN once, then they can only see this org.
  • Rotate the PIN or “Unlink all chat sessions” to kick every linked phone.
  • API keys (Scale and White Label only): create, copy once, revoke.

---

12. Billing

Open Billing.

  • Trial: 15 days, card on file.
  • Statuses: pending_payment, trialing, active, past_due, suspended, canceled, whitelabel_setup.
  • Public redirects work while trialing, active, past_due or whitelabel_setup.
  • Suspended / unpaid orgs show a blocked page instead of the destination.
  • Customer Portal (Paddle) is linked from Billing.
  • The chat bot cannot change your card.

---

13. Support tickets

In the app: Support. Subject + message.

From chat: after the PIN, ask the bot to open a ticket. Platform staff reply in the admin console.

---

14. Chat (WhatsApp, Telegram, web)

  1. Owner/admin sets the Support PIN in Settings.
  2. Message the ForeverLink bot.
  3. Give your public URL name (or the email of a member) and the PIN.
  4. Ask things like “point #12 to https://example.com/menu” or “why doesn’t QR 4 redirect?”.

Never send your panel password or 2FA codes in chat.

---

15. API (Scale and White Label)

REST at {APP_URL}/api/v1. Create a key in Settings. It is shown once.

Header:

Authorization: Bearer fl_live_…

or `X-API-Key: fl_live_…`

The key is bound to **your** organization. There is no `organization_id` you can switch.

### Scopes

| Scope | What it allows |
| --- | --- |
| `account:read` | `GET /me`, `GET /stats` |
| `links:read` | `GET /links`, `GET /links/{number}` |
| `links:write` | create / update / ranges |
| `tickets:write` | `GET/POST /tickets` |

### Endpoints

**`GET /api/v1/me`** — public URL name, plan, limits, billing status, usage.

**`GET /api/v1/links`** — query: `q`, `label`, `status`, `filter=never_clicked\|no_destination`, `page`, `per_page`, `sort=number\|clicks`.

**`GET /api/v1/links/{number}`** — detail, 14-day clicks, revisions.

**`POST /api/v1/links`**

{
  "number": 42,
  "target_url": "https://example.com",
  "label": "shop",
  "notes": "",
  "status": "active"
}

`number` is optional (next free ID).

**`PATCH /api/v1/links/{number}`** — any subset of `target_url`, `label`, `notes`, `status`.

**`POST /api/v1/links/assign-range`**

{ "from": 1, "to": 50, "label": "april", "target_url": "https://example.com/promo", "status": "active" }

**`POST /api/v1/links/generate-range`**

{ "from": 1, "to": 500 }

**`GET /api/v1/stats`** — totals and top links.

**`GET /api/v1/tickets`** · **`POST /api/v1/tickets`**

{ "subject": "QR 12 is dead", "body": "Scans show not configured", "priority": "normal" }

### Errors

{ "error": { "code": "UNAUTHORIZED", "message": "Invalid or missing API key." } }

| HTTP | Meaning |
| --- | --- |
| 401 | Missing or invalid key |
| 402 | Writes while billing is not active |
| 403 | Wrong plan, suspended org, or missing scope |
| 404 | Unknown link or route |
| 429 | Rate limit (default 60 requests / minute) |

Starter and Growth keys are rejected with `403`.

---

## 16. Why a QR does not redirect

Check in order:

1. The printed URL is `https://foreverlink.app/r/{your-org}/{number}` — URL name and number match the inventory.
2. The ID exists.
3. Status is `active`.
4. Destination is a valid `http(s)` URL.
5. Billing is `trialing` / `active` / `past_due` (not `suspended` or `pending_payment`).

---

## 17. White Label

$999 one-time software license. After payment, fill the configuration form (domain + optional self-host notes). Run it on your server, or add hosted SaaS for +$50/mo. Includes API access, documentation, and product support. Not a paid installation project.

Inventory above 25,000 IDs on Scale is sold as **5,000-ID packs** at $19/month. Add them at checkout or in Billing.

### Custom domain (Scale and White Label)

Print QR / NFC on **your** host (`https://links.yourbrand.com/r/42`) instead of `foreverlink.app`.

1. In **Settings → Custom domain** save a **subdomain** (`links.yourbrand.com`). Do not use the bare domain.
2. In your DNS panel create **one CNAME**:
   - **Type:** CNAME
   - **Name / host:** `links` (most panels) or `links.yourbrand.com` if they ask for the FQDN
   - **Target / points to:** `foreverlink.app`
   - **Cloudflare proxy:** Proxied (orange cloud) — this is how HTTPS works on your hostname
   - **TTL:** Auto
3. Wait 1–15 minutes. Click **Verify DNS**.
4. Download QRs again. They now encode `https://links.yourbrand.com/r/{number}`.

Do **not** create an A record to an IP. Do **not** CNAME the apex (`yourbrand.com`) unless your DNS has ALIAS/ANAME.

If Verify fails and you use Cloudflare, the CNAME may be hidden (flattening). Add the **TXT** shown under “Verify still fails?” (`_foreverlink.links.yourbrand.com` = the token). Old `https://foreverlink.app/r/{org}/{number}` URLs keep working.

---

Need a human? [Contact](/contact) or open a ticket in the app.
Start 15-day
free trial