Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@
"label": "membership",
"title1": "One community.",
"title2": "Two tiers. One premium path.",
"sub": "The community is the product. Inference is the superpower you add; GLM 5.3 is the frontier option for members.",
"sub": "The community is the product. Inference is the superpower you add on nan_member; GLM 5.3 is the frontier option for members.",
"perVat": "/mo · VAT included",
"perTaxes": "/mo · taxes included",
"inferenceIncluded": "inference included",
Expand All @@ -360,9 +360,9 @@
"Discord access",
"Member-only channels",
"Live discussions, builds, AMAs",
"Events, workshops and hackathons",
"Upgrade to inference whenever you want"
"Events, workshops and hackathons"
],
"communityNote": "Discord and events only: no API key and no model calls. Inference is included in nan_member (70€/mo).",
"communityCond": "No commitment. Cancel anytime. Billed in euros from any region.",
"communityCta": "Join the community",
"premiumIncludes": [
Expand Down Expand Up @@ -424,7 +424,7 @@
},
{
"q": "How does the cluster work?",
"a": "The models run 24/7 on a shared inference cluster. Each member gets a personal API key compatible with OpenAI: change the base_url and you're in."
"a": "The models run 24/7 on a shared inference cluster. Each nan_member (70€/mo, inference included) gets a personal API key compatible with OpenAI: change the base_url and you're in. The 14,99€ NaN Community plan runs no models and has no API key."
},
{
"q": "Is it really unlimited tokens?",
Expand Down Expand Up @@ -521,7 +521,7 @@
"leadA": "This doc explains how to connect your tools to our GPUs. The cluster runs open models with an OpenAI-compatible API. If something accepts a ",
"leadB": ", it works with NaN.",
"apiKeyH": "Your API key",
"apiKeyP1": "To get your API key you must be a NaN community member. Generate it from your user settings under ",
"apiKeyP1": "To get your API key you need the nan_member plan (70€/mo, inference included). The 14,99€ NaN Community plan has no inference and cannot create a key. Generate it from your user settings under ",
"apiKeyStrong": "API Keys",
"apiKeyP2": " on ",
"apiKeyP3": ". It is personal and non-transferable.",
Expand Down
10 changes: 5 additions & 5 deletions i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@
"label": "membresía",
"title1": "Una comunidad.",
"title2": "Dos tiers. Un camino premium.",
"sub": "La comunidad es el producto. La inferencia es el superpoder que le añades; GLM 5.3 es la opción frontier para miembros.",
"sub": "La comunidad es el producto. La inferencia es el superpoder que se añade con nan_member; GLM 5.3 es la opción frontier para miembros.",
"perVat": "/mes · IVA incluido",
"perTaxes": "/mes · impuestos incluidos",
"inferenceIncluded": "inferencia incluida",
Expand All @@ -360,9 +360,9 @@
"Acceso a Discord",
"Canales solo para miembros",
"Charlas en directo, builds, AMAs",
"Eventos, workshops y hackathons",
"Pasa a inferencia cuando quieras"
"Eventos, workshops y hackathons"
],
"communityNote": "Solo Discord y eventos: sin API key y sin llamadas a modelos. La inferencia está incluida en nan_member (70€/mes).",
"communityCond": "Sin compromiso. Cancela cuando quieras. Se factura en euros desde cualquier región.",
"communityCta": "Únete a la comunidad",
"premiumIncludes": [
Expand Down Expand Up @@ -424,7 +424,7 @@
},
{
"q": "¿Cómo funciona el cluster?",
"a": "Los modelos corren 24/7 en un cluster de inferencia compartido. Cada miembro recibe una API key personal compatible con OpenAI: cambias el base_url y ya estás dentro."
"a": "Los modelos corren 24/7 en un cluster de inferencia compartido. Cada miembro de nan_member (70€/mes, con inferencia incluida) recibe una API key personal compatible con OpenAI: cambias el base_url y ya estás dentro. El plan NaN Community de 14,99€ no corre modelos y no tiene API key."
},
{
"q": "¿De verdad son tokens ilimitados?",
Expand Down Expand Up @@ -521,7 +521,7 @@
"leadA": "Esta doc explica cómo conectar tus herramientas a nuestras GPUs. El cluster corre modelos abiertos con una API compatible con OpenAI. Si algo acepta un ",
"leadB": ", funciona con NaN.",
"apiKeyH": "Tu API key",
"apiKeyP1": "Para conseguir tu API key tienes que ser miembro de la comunidad NaN. Genérala desde los ajustes de tu usuario, en ",
"apiKeyP1": "Para conseguir tu API key necesitas el plan nan_member (70€/mes, con inferencia incluida). El plan NaN Community de 14,99€ no tiene inferencia y no puede generar una key. Genérala desde los ajustes de tu usuario, en ",
"apiKeyStrong": "API Keys",
"apiKeyP2": ", en ",
"apiKeyP3": ". Es personal e intransferible.",
Expand Down
20 changes: 20 additions & 0 deletions src/components/nan/home/Pricing.astro
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const tiers = [
badge: tt.premiumBadge,
ref: true,
includes: tt.premiumIncludes,
note: null,
cond: tt.premiumCond,
cta: tt.premiumCta,
href: signupUrl('premium'),
Expand All @@ -38,6 +39,7 @@ const tiers = [
badge: tt.inferenceIncluded,
ref: true,
includes: tt.memberIncludes,
note: null,
cond: tt.memberCond,
cta: tt.memberCta,
href: signupUrl('inference'),
Expand All @@ -50,6 +52,10 @@ const tiers = [
badge: null,
ref: false,
includes: tt.communityIncludes,
// The negative half of the offer, stated before the Checkout rather than
// only on /community: prospects bought 14,99€ expecting the API key the
// 70€ tier sells and cancelled within the hour. See communityNote.
note: tt.communityNote,
cond: tt.communityCond,
cta: tt.communityCta,
href: signupUrl('community'),
Expand Down Expand Up @@ -101,6 +107,7 @@ const wsDocs = lang === 'es' ? '/es/docs/workspaces' : '/docs/workspaces';
<ul class="ptier__list">
{tier.includes.map((item) => <li>{item}</li>)}
</ul>
{tier.note && <p class="ptier__note">{tier.note}</p>}

<a
class:list={['btn', 'ptier__cta', tier.primary ? 'btn-primary' : 'btn-ghost']}
Expand Down Expand Up @@ -261,6 +268,19 @@ const wsDocs = lang === 'es' ? '/es/docs/workspaces' : '/docs/workspaces';
background: var(--color-violet);
}

/* What the tier does NOT include, next to the list instead of in fine print
at the bottom: this is the line that stops someone buying 14,99€ expecting
an API key. */
.ptier__note {
font-family: var(--font-mono);
font-size: 12px;
line-height: 1.6;
color: var(--color-text-dim);
border-left: 2px solid var(--color-violet);
padding-left: var(--space-3);
margin: 0 0 var(--space-6);
}

/* botón anclado abajo; los 3 CTAs quedan a la misma altura */
.ptier__cta { width: 100%; margin-top: auto; }
.ptier__cond {
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs-es/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ La API de NaN es compatible con OpenAI. Solo necesitas dos datos, una **base URL

### Consigue tu API key

Tienes que ser miembro de la comunidad NaN. Entra en [cloud.nan.builders](https://cloud.nan.builders/), abre los ajustes de usuario y ve a la sección **API Keys** para generar la tuya.
Necesitas **nan_member** (70€/mes) o GLM 5.3 premium (200€/mes): los dos incluyen inferencia. El plan NaN Community de 14,99€ no corre modelos, así que no tiene API key. Entra en [cloud.nan.builders](https://cloud.nan.builders/), abre los ajustes de usuario y ve a la sección **API Keys** para generar la tuya.

La clave es personal e intransferible, y se muestra una sola vez: cópiala en cuanto la generes. Si la pierdes, no pasa nada, genera otra y borra la vieja desde el mismo panel.

Expand Down
2 changes: 1 addition & 1 deletion src/content/docs-es/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ group: Primeros pasos
Esta documentación explica cómo conectar tus herramientas a nuestras GPUs. El clúster ejecuta modelos abiertos con una API compatible con OpenAI. Si algo acepta una `base URL` y una `API key`, funciona con NaN. La excepción es una herramienta que hable otro protocolo: [Claude Code](/es/docs/claude-code) habla con la API de Anthropic, no con una compatible con OpenAI, así que llega al clúster a través de OpenCode o de una pasarela local. Su página explica las dos formas.

> **Para conseguir tu API Key**
> Tienes que ser miembro de la comunidad de NaN. Puedes generar tu API Key desde los ajustes de usuario, en el apartado "API Keys" de la [plataforma](https://cloud.nan.builders/). La key es personal e intransferible.
> Necesitas un plan con inferencia: **nan_member** (70€/mes) o GLM 5.3 premium (200€/mes). Puedes generar tu API Key desde los ajustes de usuario, en el apartado "API Keys" de la [plataforma](https://cloud.nan.builders/). El plan NaN Community de 14,99€ cubre solo Discord y eventos: no corre modelos y no puede generar una key. La key es personal e intransferible.

## Lo esencial

Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The NaN API is OpenAI-compatible. You only need two things, a **base URL** and a

### Get your API key

You have to be a member of the NaN community. Go to [cloud.nan.builders](https://cloud.nan.builders/), open your user settings and go to the **API Keys** section to generate yours.
You need **nan_member** (70€/mo) or GLM 5.3 premium (200€/mo): both include inference. The 14,99€ NaN Community plan runs no models, so it has no API key. Go to [cloud.nan.builders](https://cloud.nan.builders/), open your user settings and go to the **API Keys** section to generate yours.

The key is personal, non-transferable, and shown only once: copy it as soon as you generate it. If you lose it, nothing breaks, generate another one and delete the old one from the same panel.

Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ group: Get started
This documentation explains how to connect your tools to our GPUs. The cluster runs open models behind an OpenAI-compatible API. If something accepts a `base URL` and an `API key`, it works with NaN. The exception is a tool that speaks a different protocol: [Claude Code](/docs/claude-code) talks to Anthropic's API, not to an OpenAI-compatible one, so it reaches the cluster through OpenCode or through a local gateway. Its page explains both.

> **To get your API Key**
> You have to be a member of the NaN community. You can generate your API Key from the user settings, under "API Keys" on the [platform](https://cloud.nan.builders/). The key is personal and non-transferable.
> You need an inference plan: **nan_member** (70€/mo) or GLM 5.3 premium (200€/mo). Generate the key from the user settings, under "API Keys", on the [platform](https://cloud.nan.builders/). The 14,99€ NaN Community plan covers Discord and events only, so it runs no models and cannot create a key. The key is personal and non-transferable.

## The essentials

Expand Down
71 changes: 71 additions & 0 deletions src/tests/landing/pricing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,74 @@ describe('Pricing section — workspaces block', () => {
expect(source.indexOf('id="workspaces"')).toBeGreaterThan(source.indexOf('tiers.map('));
});
});

/**
* The 14,99€ community tier sells Discord and events. It has never sold
* inference, but three surfaces said otherwise or said it ambiguously, and
* prospects paid, found out, and cancelled within the hour:
*
* - the pricing card's last bullet promised "upgrade to inference whenever
* you want", while the upgrade is a manual invite when capacity frees up;
* - the FAQ said "each member gets a personal API key", on a page whose
* cheapest tier is "NaN Community";
* - the docs said "you have to be a member of the NaN community", which the
* 14,99€ buyer satisfies literally and cannot act on.
*
* Members wrote it verbatim in their cancellation feedback ("NO SE PUEDE USAR
* SIN CONTRATAR EL PLAN DE $70", "the docs said that I can create an API
* KEY"), so these asserts are the memory of that bill.
*/
describe.each(locales)('Pricing copy — community tier is Discord only (%s)', (locale) => {
test('states before the Checkout that inference and the API key are not included', () => {
const note = t('nan.pricing.communityNote', locale);
expect(note).toMatch(/nan_member/);
expect(note).toMatch(/API key/i);
expect(note).toMatch(/70€/);
expect(note).toMatch(/(no API key|sin API key)/i);
});

/**
* The bullets sell what the plan gives. Inference is the note's job, so the
* list must not mention it at all: a negative line in a bulleted list of
* inclusions inherits the violet "included" dot and reads as a feature.
*/
test('the bullets never promise inference on demand', () => {
const copy = tArr('nan.pricing.communityIncludes', locale).join(' ');
expect(copy).not.toMatch(/inference|inferencia|API key/i);
});

test('the section intro does not sell inference as an add-on to the cheap tier', () => {
const sub = t('nan.pricing.sub', locale);
expect(sub).toMatch(/nan_member/);
});

test('the cluster FAQ names the plan that owns the key', () => {
const faq = tObj<{ items?: FaqItem[] }>('nan.faq', locale);
const answer = (faq.items ?? []).map((item) => item.a).find((a) => /API key/i.test(a));
expect(answer).toBeDefined();
expect(answer).toMatch(/nan_member/);
expect(answer).toMatch(/70€/);
});

test('the card renders the note, so the copy cannot sit unused in the dictionary', () => {
expect(tiers).toContain('note: tt.communityNote');
expect(source).toContain('{tier.note && <p class="ptier__note">{tier.note}</p>}');
});

/**
* The docs are where the churned members said they read it, and both locales
* ship their own files, so both are read here rather than trusting the fix to
* be remembered twice.
*/
test('the docs send a buyer to nan_member before saying how to create a key', () => {
const files =
locale === 'en'
? ['src/content/docs/intro.md', 'src/content/docs/getting-started.mdx']
: ['src/content/docs-es/intro.md', 'src/content/docs-es/getting-started.mdx'];
for (const file of files) {
const body = readFileSync(resolve(here, '../../../', file), 'utf-8');
expect(body, file).toMatch(/nan_member/);
expect(body, file).not.toMatch(/(have to be a member of the NaN community|ser miembro de la comunidad de? ?NaN)/i);
}
});
});
Loading