Appearance
Account API
The Account API returns the authenticated creator's account details: plan tier, click usage for the current billing period, included click limit, overage rate, trial status, and billing period boundaries.
Use it to display usage dashboards, enforce click limits in your own tooling, or react programmatically to quota thresholds.
Base path: https://api.fyralynx.com/v1
Tier required: Publisher or Enterprise
The Account Object
json
{
"creatorId": "01HX4Z9Y3ABCDEF1234567890AB",
"email": "creator@example.com",
"plan": {
"planId": "publisher",
"displayName": "Publisher",
"monthlyPriceUsd": 39.00,
"annualPriceUsd": 374.00,
"billingCycle": "monthly",
"includedClicks": 50000,
"overageRatePerThousand": 1.50,
"hasApiAccess": true,
"hasBulkAccess": false,
"hasWebhooks": false,
"hasSla": false
},
"clicksUsedThisPeriod": 12450,
"clicksIncluded": 50000,
"clicksRemaining": 37550,
"usagePct": 24.9,
"overageClicksThisPeriod": 0,
"estimatedOverageChargeUsd": 0.00,
"billingPeriodStart": "2026-05-01",
"billingPeriodEnd": "2026-05-31",
"trialActive": false,
"trialEndsAt": null,
"billingCurrency": "USD",
"region": "US",
"apiKeyCount": 2,
"accountCreatedAt": "2026-01-15T09:00:00Z"
}Field reference
| Field | Type | Description |
|---|---|---|
creatorId | string | Unique creator account identifier. |
email | string | Account email address. |
plan.planId | string | Plan tier: free, creator, pro, publisher, enterprise. |
plan.displayName | string | Human-readable plan name. |
plan.monthlyPriceUsd | number | Base price in USD per month. 0 for Free tier. |
plan.annualPriceUsd | number | Annual price in USD (20% discount vs monthly × 12). |
plan.billingCycle | string | monthly or annual. |
plan.includedClicks | number | Clicks included in the plan per billing period. |
plan.overageRatePerThousand | number | USD charged per 1,000 clicks over the included limit. 0 for Free (hard cap, no overage). |
plan.hasApiAccess | boolean | Whether the plan includes REST API access. |
plan.hasBulkAccess | boolean | Whether POST /links/bulk is available. |
plan.hasWebhooks | boolean | Whether webhooks are enabled. |
plan.hasSla | boolean | Whether an SLA contract is in effect. |
clicksUsedThisPeriod | number | Clicks consumed since billingPeriodStart. |
clicksIncluded | number | Clicks included in the current plan period. |
clicksRemaining | number | max(0, clicksIncluded − clicksUsedThisPeriod). |
usagePct | number | clicksUsedThisPeriod / clicksIncluded × 100. |
overageClicksThisPeriod | number | Clicks above clicksIncluded. 0 if within limit. |
estimatedOverageChargeUsd | number | max(0, overageClicksThisPeriod / 1000 × overageRatePerThousand). |
billingPeriodStart | string (ISO 8601 date) | Start of the current billing period. |
billingPeriodEnd | string (ISO 8601 date) | End of the current billing period (inclusive). |
trialActive | boolean | true if a 14-day trial is currently active. |
trialEndsAt | string | null | ISO 8601 datetime when the trial expires (and the card on file is auto-charged). null if no active trial. |
billingCurrency | string | ISO 4217 code of the creator's billing currency. |
region | string | Creator's declared account region (ISO 3166-1 alpha-2). |
apiKeyCount | number | Number of active API keys on the account. |
accountCreatedAt | string (ISO 8601) | When the Fyralynx account was created. |
GET /account - Get account information
Returns the full account object for the authenticated creator.
Tier: Publisher+
Note: This endpoint returns information for the creator associated with the Bearer API key. It never returns data about other accounts.
Response - 200 OK
Full account object as shown above.
curl example
bash
curl "https://api.fyralynx.com/v1/account" \
-H "Authorization: Bearer $FYRALYNX_API_KEY"TypeScript example
typescript
interface PlanInfo {
planId: 'free' | 'creator' | 'pro' | 'publisher' | 'enterprise';
displayName: string;
monthlyPriceUsd: number;
annualPriceUsd: number;
billingCycle: 'monthly' | 'annual';
includedClicks: number;
overageRatePerThousand: number;
hasApiAccess: boolean;
hasBulkAccess: boolean;
hasWebhooks: boolean;
hasSla: boolean;
}
interface AccountInfo {
creatorId: string;
email: string;
plan: PlanInfo;
clicksUsedThisPeriod: number;
clicksIncluded: number;
clicksRemaining: number;
usagePct: number;
overageClicksThisPeriod: number;
estimatedOverageChargeUsd: number;
billingPeriodStart: string;
billingPeriodEnd: string;
trialActive: boolean;
trialEndsAt: string | null;
billingCurrency: string;
region: string;
apiKeyCount: number;
accountCreatedAt: string;
}
async function getAccount(): Promise<AccountInfo> {
const response = await fetch('https://api.fyralynx.com/v1/account', {
headers: {
Authorization: `Bearer ${process.env.FYRALYNX_API_KEY}`,
},
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Fyralynx ${response.status}: ${error.code}`);
}
const { data } = await response.json();
return data;
}Python example
python
import httpx
def get_account() -> dict:
response = httpx.get(
"https://api.fyralynx.com/v1/account",
headers={"Authorization": f"Bearer {FYRALYNX_API_KEY}"},
)
response.raise_for_status()
return response.json()["data"]Plan Tiers
| Plan | planId | Price | Clicks | Overage | API | Bulk | Webhooks |
|---|---|---|---|---|---|---|---|
| Free | free | $0/mo | 500 (hard cap) | None | No | No | No |
| Creator | creator | $5/mo | 2,000 | $2.50/1k | No | No | No |
| Pro | pro | $15/mo | 10,000 | $2/1k | No | No | No |
| Publisher | publisher | $39/mo | 50,000 | $1.50/1k | Yes | No | No |
| Enterprise | enterprise | $299+/mo | 500,000 | $1/1k | Yes | Yes (100/request) | Yes |
Annual billing saves 20%:
| Plan | Monthly | Annual (billed annually) |
|---|---|---|
| Creator | $5 | $48 ($4/mo effective) |
| Pro | $15 | $144 ($12/mo effective) |
| Publisher | $39 | $374 ($31/mo effective) |
| Enterprise | $299+ | Custom |
Click Counting Rules
A click is counted when the edge redirector (go.fyralynx.com) serves an HTTP 302 response for a valid routing request. The following are not counted:
| Event | Counted? | Reason |
|---|---|---|
Real visitor follows a routeUrl | ✅ Yes | Normal affiliate traffic |
| Passthrough link followed | ✅ Yes | Edge still serves a 302 |
POST /route endpoint call | ❌ No | No link created, no redirect served |
| CRC Simulate action (extension) | ❌ No | Simulation flag detected |
| Bot traffic (CF Bot Score < 30) | ❌ No | Detected as non-human |
| Rate-limited request (429 response) | ❌ No | Passed through without routing |
| Health check probes | ❌ No | Internal probes only |
The click count resets on the 1st of each month (UTC midnight).
Trial Lifecycle
| State | trialActive | trialEndsAt | Description |
|---|---|---|---|
| No trial | false | null | Creator is on their selected plan without a trial. |
| Active trial | true | ISO 8601 datetime | 14-day trial in progress. Full plan features available. |
| Trial expired → paid | false | null | Trial converted to paid plan. The card on file was charged automatically. |
| Trial expired → cancelled | false | Past datetime | Trial cancelled before end. Account downgraded to Free, no charge. |
14-day trial details:
- Available on Creator, Pro, and Publisher tiers, granted once per plan.
- Payment method required on file before the trial starts (Razorpay).
- Full feature access during the trial.
- When the trial ends, the payment method on file is charged automatically and billing recurs on the chosen monthly or annual cycle. No charge if the subscription is cancelled before
trialEndsAt. - Cancelling before the trial ends forfeits a future trial on that plan (re-subscribing charges immediately). There is no trial extension.
When trialActive: true and trialEndsAt is within 48 hours, surface a reminder that the card on file will be charged, so users can cancel first if they wish.
Common Patterns
Usage dashboard widget
typescript
async function buildUsageWidget() {
const account = await getAccount();
const usagePct = account.usagePct;
const status =
usagePct >= 100 ? 'exceeded' :
usagePct >= 80 ? 'warning' :
'ok';
return {
planName: account.plan.displayName,
clicksUsed: account.clicksUsedThisPeriod,
clicksIncluded: account.clicksIncluded,
clicksRemaining: account.clicksRemaining,
usagePct: account.usagePct,
status,
billingPeriodEnd: account.billingPeriodEnd,
overageCharge: account.estimatedOverageChargeUsd,
trialActive: account.trialActive,
trialEndsAt: account.trialEndsAt,
};
}Check if bulk is available before calling /links/bulk
typescript
async function createLinksSafely(urls: string[]): Promise<Link[]> {
const account = await getAccount();
if (!account.plan.hasBulkAccess) {
// Fall back to sequential individual creates
return Promise.all(
urls.map(url => createLink({ url, preset: 'auto' })),
);
}
// Enterprise: use bulk endpoint
return createLinksInBatches(urls);
}Notify users approaching their quota
typescript
async function checkQuotaWarning(): Promise<void> {
const account = await getAccount();
if (account.plan.planId === 'free' && account.usagePct >= 80) {
console.warn(
`Free tier usage at ${account.usagePct.toFixed(1)}%. ` +
`Routing will stop at 500 clicks. Upgrade at fyralynx.com/pricing.`
);
} else if (account.usagePct >= 100 && account.plan.overageRatePerThousand === 0) {
console.warn('Monthly click cap reached. Routing is stopped until period reset.');
} else if (account.usagePct >= 80) {
console.warn(
`${account.usagePct.toFixed(1)}% of ${account.clicksIncluded.toLocaleString()} ` +
`clicks used. Estimated overage: $${account.estimatedOverageChargeUsd.toFixed(2)}.`
);
}
}WordPress plugin - cache account tier to avoid per-request API calls
php
function fyralynx_get_account_cached(): array {
$cache_key = 'fyralynx_account_' . md5(get_option('fyralynx_api_key'));
$cached = get_transient($cache_key);
if ($cached !== false) {
return $cached;
}
$response = wp_remote_get(
'https://api.fyralynx.com/v1/account',
['headers' => ['Authorization' => 'Bearer ' . get_option('fyralynx_api_key')]]
);
if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) {
return ['plan' => ['planId' => 'unknown']];
}
$data = json_decode(wp_remote_retrieve_body($response), true)['data'];
// Cache for 1 hour - plan tier rarely changes
set_transient($cache_key, $data, HOUR_IN_SECONDS);
return $data;
}Overage Calculation
Overage is calculated at the end of each billing month and charged automatically to the payment method on file (paid tiers).
overage_clicks = max(0, clicksUsedThisPeriod − clicksIncluded)
overage_charge_usd = overage_clicks / 1000 × overageRatePerThousandThe estimatedOverageChargeUsd field in the account response reflects the current projected overage charge if the billing period ended now.
Enterprise tier: Overages are invoiced monthly rather than auto-charged. Enterprise accounts can set a custom overage alert threshold via the dashboard.
VAT & Regional Billing
Billing currency and applicable tax are determined by the creator's declared account region:
| Region | Currency | Tax |
|---|---|---|
India (IN) | INR | 18% GST |
UAE (AE) | AED | 5% VAT |
Saudi Arabia (SA) | SAR | 15% VAT |
United Kingdom (GB) | GBP | 20% VAT |
Australia (AU) | AUD | 10% GST |
| EU countries | EUR | Local VAT (15-27%) |
United States (US) | USD | No federal digital services tax |
| All other regions | USD | Local digital services tax where applicable |
Tax is always included in the monthlyPriceUsd and annualPriceUsd displayed in plan information. The billingCurrency field on the account object reflects the actual billing currency for your account.
API Health Check (No Auth)
For external uptime monitors, GET /health does not require authentication:
bash
curl "https://api.fyralynx.com/v1/health"json
{
"status": "ok",
"kvLatencyMs": 4,
"fxAgeHours": 8.3,
"workerRegion": "enam",
"timestamp": "2026-05-16T14:23:00Z"
}| Field | Description |
|---|---|
status | ok, degraded, or down. |
kvLatencyMs | KV read latency in milliseconds at the serving PoP. |
fxAgeHours | Hours since the last FX rate refresh. |
workerRegion | Cloudflare region code of the serving Worker PoP. |
timestamp | When this health check was generated (ISO 8601). |
Error Reference
| Code | Status | Description |
|---|---|---|
UNAUTHORIZED | 401 | Missing or invalid Bearer token. |
PUBLISHER_TIER_REQUIRED | 403 | API access requires Publisher or Enterprise plan. |
RATE_LIMIT_EXCEEDED | 429 | Rate limit exceeded. |
See Also
- API Overview - base URL, authentication, plan tier enforcement
- Authentication - API key generation, tier verification
- Rate Limits - click quota vs API rate limits (two separate concepts)
- Analytics API - detailed per-click records and summaries
- Webhooks -
account.usage_warningevents at 80% and 100% of monthly limit (Enterprise) - Fyralynx Pricing - full plan comparison