Skip to main content

Onboarding deep links

Aglyn staff only

Internal contract reference. The marketing site is built and deployed separately from the console (AGL-1117), so this page is the agreement between them.

The contract​

The marketing pricing page links into console signup, carrying the plan the visitor chose:

https://app.aglyn.com/signup?plan=pro&interval=year
ParamValuesMissing / unrecognized
planstarter pro business scale advanced agency enterpriseOrdinary signup
intervalmonth, year (annual accepted as a synonym)month

free is accepted as a value but produces no intent — it is a real plan but not a purchase, and a new workspace already starts there. Sending someone to a billing page to buy what they have would be worse than ignoring it.

What the console does with it​

Signup collects an organization name and provisions the workspace as part of account creation (AGL-1115), so a new user lands in a ready workspace rather than an empty chooser.

Enterprise never routes to checkout. It is quoted, not bought, so the CTA lands on contact-sales and the staff enterprise-billing flow (AGL-1110) takes it from there. A checkout that cannot price the plan is a dead end.

Rules this parser follows, and why​

Parsing lives in one place — parseOnboardingPlanIntent in @aglyn/aglyn — and is deliberately forgiving, because the pricing page will be edited by people who have never read our enum, and we cannot deploy the two in lockstep:

  • A bad param degrades to ordinary signup. It must never break signup, and — far worse — must never silently start someone on a plan they did not pick.
  • An unrecognized interval falls to month, never year. Guessing the longer commitment from a malformed link is the expensive direction to be wrong in.
  • Casing and stray whitespace are the same intent; ?plan=PRO%20 is pro.
  • A repeated param takes the first value. Next hands back a string[], and joining would produce "pro,free" and lose a valid intent.

Known gap​

The Google sign-up buttons submit no form, so there is no organization name to provision from — those accounts still land on the workspace picker. Closing that needs the two-step flow (account → org details) that AGL-1115 also suggests, which is a larger change than the field.

Org creation is best-effort: the account exists and the user is signed in before it runs, so a failure falls through to the workspace picker rather than surfacing as a failed sign-up. A 409 (slug taken) also falls through — the org was not created, and inventing a suffix would hand someone a workspace URL they never chose.