Skip to content

Commit 5bf6d16

Browse files
pablomogamonclaude
andcommitted
The way out is a deep link, not the dashboard lobby
The exhausted-credits message pointed at DASHBOARD_URL and left the reader to find billing, find the button, find the modal. The app gives that modal a URL (/billing?topup=open, since app PR #1972), so the message now hands over the purchase directly, and names /plans for the upgrade path. Constants live in open-url.ts beside the other canonical URLs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 92383fe commit 5bf6d16

3 files changed

Lines changed: 11 additions & 2 deletions

File tree

‎src/core/errors.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* a `next_action`, and optional `suggested_commands`. Agents (and humans) can
66
* react to the code and follow the suggested command without guessing.
77
*/
8-
import { DASHBOARD_URL } from "./open-url.ts";
8+
import { BILLING_TOPUP_URL, PLANS_URL } from "./open-url.ts";
99

1010
export type ErrorCode =
1111
| "AUTH_MISSING"
@@ -96,7 +96,7 @@ export function quotaExhausted(
9696
const renewLine = "Credits renew at the end of the billing period — run `zenrows usage` for the date.";
9797
const claimLine = claimUrl
9898
? `You are on the Zenrows Free plan. Claim your account to keep your usage and add credits: ${claimUrl}. ${renewLine}`
99-
: `You are out of Zenrows credits. ${renewLine} To carry on now, add credits or upgrade your plan: ${DASHBOARD_URL}`;
99+
: `You are out of Zenrows credits. ${renewLine} To carry on now, add a credit pack (${BILLING_TOPUP_URL} opens the purchase directly) or upgrade your plan: ${PLANS_URL}`;
100100
const detail = opts.detail ? `${opts.detail.replace(/\.\s*$/, "")}. ` : "";
101101
return new ToolkitError({
102102
code: "POLICY_MAX_CREDITS_EXCEEDED",

‎src/core/open-url.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ export const AGENT_SIGNUP_API_URL = "https://app.zenrows.com/api/agent/signup";
1010
/** Well-known path advertising the agent-auth endpoints (signup discovery). */
1111
export const WELL_KNOWN_PROTECTED_RESOURCE = "/.well-known/oauth-protected-resource";
1212
export const DASHBOARD_URL = "https://app.zenrows.com/dashboard";
13+
/** Lands on Billing with the credit-pack purchase modal already open (app PR #1972). */
14+
export const BILLING_TOPUP_URL = "https://app.zenrows.com/billing?topup=open";
15+
export const PLANS_URL = "https://app.zenrows.com/plans";
1316
export const DOCS_URL = "https://docs.zenrows.com";
1417

1518
/** Append query params to a URL (used to attach anonymous `utm_*` attribution). */

‎tests/errors.test.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ test("quotaExhausted says the allowance renews, on both account states", () => {
1616
for (const claim of ["https://x/claim/t", undefined]) {
1717
const err = quotaExhausted("https://api.zenrows.com/v1/?url=x", claim);
1818
assert.match(err.next_action, /renew/i);
19+
if (!claim) {
20+
// The route out is a deep link that lands with the purchase already open,
21+
// not a generic dashboard URL the reader has to navigate from.
22+
assert.ok(err.next_action.includes("https://app.zenrows.com/billing?topup=open"));
23+
assert.ok(err.next_action.includes("https://app.zenrows.com/plans"));
24+
}
1925
assert.ok(
2026
err.suggested_commands?.includes("zenrows usage"),
2127
"the exact renewal date is one command away, so point at it in both states",

0 commit comments

Comments
 (0)