vybekiit 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +6457 -6312
- package/dist/global-skills/aws-serverless/SKILL.md +44 -44
- package/dist/global-skills/aws-serverless/assets/powertools-handler.py +2 -1
- package/dist/global-skills/aws-serverless/references/api-gateway.md +50 -470
- package/dist/global-skills/aws-serverless/references/architecture.md +47 -186
- package/dist/global-skills/aws-serverless/references/concurrency.md +44 -158
- package/dist/global-skills/aws-serverless/references/deployment.md +1 -1
- package/dist/global-skills/aws-serverless/references/event-sources.md +72 -391
- package/dist/global-skills/aws-serverless/references/lambda.md +69 -428
- package/dist/global-skills/aws-serverless/references/orchestration.md +65 -384
- package/dist/global-skills/aws-serverless/references/production.md +78 -415
- package/dist/global-skills/aws-serverless/references/troubleshooting.md +79 -626
- package/dist/global-skills/email-best-practices/.github/workflows/sync-skills.yml +30 -0
- package/dist/global-skills/email-best-practices/README.md +63 -0
- package/dist/global-skills/email-best-practices/references/accessibility.md +189 -0
- package/dist/global-skills/email-best-practices/references/compliance.md +125 -0
- package/dist/global-skills/email-best-practices/references/deliverability.md +121 -0
- package/dist/global-skills/email-best-practices/references/email-capture.md +129 -0
- package/dist/global-skills/email-best-practices/references/email-types.md +173 -0
- package/dist/global-skills/email-best-practices/references/list-management.md +157 -0
- package/dist/global-skills/email-best-practices/references/marketing-emails.md +115 -0
- package/dist/global-skills/email-best-practices/references/sending-reliability.md +155 -0
- package/dist/global-skills/email-best-practices/references/transactional-email-catalog.md +418 -0
- package/dist/global-skills/email-best-practices/references/transactional-emails.md +92 -0
- package/dist/global-skills/email-best-practices/references/webhooks-events.md +167 -0
- package/dist/global-skills/email-best-practices/tests/README.md +35 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/01-spam-deliverability.md +46 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/02-multi-region-compliance.md +48 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/03-retry-idempotency.md +36 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/04-webhook-bounce-handling.md +52 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/05-new-saas-email-plan.md +51 -0
- package/dist/global-skills/instrument-feature-flags/references/usage.md +35 -0
- package/dist/global-skills/instrument-product-analytics/SKILL.md +1 -1
- package/dist/global-skills/instrument-product-analytics/references/android.md +36 -0
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +1 -0
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +37 -0
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +3 -2
- package/dist/global-skills/instrument-product-analytics/references/usage.md +35 -0
- package/dist/global-skills/neon/SKILL.md +27 -20
- package/dist/global-skills/neon-ai-gateway/SKILL.md +68 -2
- package/dist/global-skills/neon-functions/SKILL.md +7 -7
- package/dist/global-skills/neon-object-storage/SKILL.md +2 -2
- package/dist/global-skills/neon-postgres/SKILL.md +5 -5
- package/dist/global-skills/neon-postgres/references/neon-sdk.md +262 -0
- package/dist/global-skills/neon-postgres-branches/SKILL.md +1 -1
- package/dist/global-skills/stripe-best-practices/SKILL.md +11 -6
- package/dist/global-skills/stripe-best-practices/references/billing.md +5 -0
- package/dist/global-skills/stripe-best-practices/references/payments.md +4 -2
- package/dist/global-skills/stripe-best-practices/references/tax.md +78 -8
- package/package.json +7 -7
|
@@ -16,7 +16,7 @@ description: >-
|
|
|
16
16
|
|
|
17
17
|
# Neon AI Gateway
|
|
18
18
|
|
|
19
|
-
This is a
|
|
19
|
+
This is a public beta feature and only available in `us-east-2`. The Neon AI Gateway is the LLM inference layer built into your Neon branch: one API and one Neon credential give you access to frontier and open-source models from Anthropic, OpenAI, Google, Meta, Alibaba, DeepSeek, and Databricks — powered by Databricks. Your existing OpenAI/Anthropic/Gemini SDK works by changing only the base URL.
|
|
20
20
|
|
|
21
21
|
Use this skill to help the user send model calls through the gateway, wire it into the AI SDK or Mastra, and switch providers without rewiring code. Deliver a working inference request, a configured agent, or a precise answer from the official Neon docs.
|
|
22
22
|
|
|
@@ -215,9 +215,75 @@ Use a model's catalog ID directly in the `model` field — e.g. `claude-sonnet-4
|
|
|
215
215
|
- **models.dev Neon provider page: https://models.dev/providers/neon** — the canonical, always-current list of the Neon provider's model IDs and their underlying models. The machine-readable catalog is at https://models.dev/api.json (the `neon` key).
|
|
216
216
|
- **Models doc:** see Further reading.
|
|
217
217
|
|
|
218
|
+
## List available models at runtime (`/v1/models`)
|
|
219
|
+
|
|
220
|
+
The gateway also exposes the model catalog **live from your own branch endpoint**, so an app or agent can discover exactly which models this branch serves without hard-coding the list. It is an OpenAI-compatible list endpoint, served **only on the unified dialect** (`/v1`):
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
curl "$NEON_AI_GATEWAY_BASE_URL/v1/models" \
|
|
224
|
+
-H "Authorization: Bearer $NEON_AI_GATEWAY_TOKEN"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
- `GET ${NEON_AI_GATEWAY_BASE_URL}/v1/models` → **200**
|
|
228
|
+
- `GET ${NEON_AI_GATEWAY_BASE_URL}/openai/v1/models` → **404** (not served on the Responses dialect — use `/v1`)
|
|
229
|
+
|
|
230
|
+
**Getting the credentials for the request.** Both values come from the same branch-scoped Neon credential the gateway uses everywhere else — you never manage a provider key:
|
|
231
|
+
|
|
232
|
+
- **Provision via `neon.ts` (recommended).** Enable `preview.aiGateway` in `neon.ts` and run `neon deploy` (or `neon config apply`). Provisioning, `neon link`, and `neon checkout` pull `NEON_AI_GATEWAY_TOKEN` + `NEON_AI_GATEWAY_BASE_URL` into your local `.env.local`; inside a deployed Neon Function they're injected automatically. See **Setup** and **Environment variables** above.
|
|
233
|
+
- **Pull into the environment via CLI.** On a branch that already has the gateway enabled, `neon env pull` writes the two vars to `.env`/`.env.local`, or `neon-env run -- <cmd>` injects them at runtime without a file.
|
|
234
|
+
- **Provision via the Console UI.** Enable the AI Gateway on the branch in the Neon Console and copy the branch's gateway base URL and a Neon credential (token) from the project's connection/credentials view.
|
|
235
|
+
|
|
236
|
+
Any Neon credential (`nt_live_...`) valid for the branch works as the bearer token; `NEON_AI_GATEWAY_BASE_URL` is the bare branch host (no path).
|
|
237
|
+
|
|
238
|
+
**Response shape** — OpenAI/OpenRouter-compatible list:
|
|
239
|
+
|
|
240
|
+
```jsonc
|
|
241
|
+
{
|
|
242
|
+
"object": "list",
|
|
243
|
+
"data": [
|
|
244
|
+
{
|
|
245
|
+
"id": "claude-sonnet-4-6", // catalog model ID — use directly in the `model` field
|
|
246
|
+
"canonical_slug": "claude-sonnet-4-6",
|
|
247
|
+
"name": "Claude Sonnet 4.6", // human-readable display name
|
|
248
|
+
"object": "model",
|
|
249
|
+
"owned_by": "anthropic", // anthropic | openai | google | meta | alibaba | databricks
|
|
250
|
+
"created": 0,
|
|
251
|
+
"enabled": true,
|
|
252
|
+
"context_length": null,
|
|
253
|
+
"architecture": {
|
|
254
|
+
"modality": "text->text",
|
|
255
|
+
"input_modalities": ["text"],
|
|
256
|
+
"output_modalities": ["text"],
|
|
257
|
+
"tokenizer": "Claude", // Claude | Gemini | GPT | "" (empty for open-source)
|
|
258
|
+
"instruct_type": null
|
|
259
|
+
},
|
|
260
|
+
"top_provider": {
|
|
261
|
+
"is_moderated": false,
|
|
262
|
+
"context_length": null,
|
|
263
|
+
"max_completion_tokens": null
|
|
264
|
+
},
|
|
265
|
+
"pricing": null,
|
|
266
|
+
"per_request_limits": null
|
|
267
|
+
}
|
|
268
|
+
// ... one entry per model in the branch's catalog
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
> Note: `context_length`, `pricing`, and `per_request_limits` are currently `null` and `created` is `0` for every entry — for context windows, pricing, and capabilities use the models.dev catalog above. Use `/v1/models` when you need the live, branch-scoped list of servable model IDs (e.g. to populate a model picker or validate a `model` before a request).
|
|
274
|
+
|
|
218
275
|
## Availability
|
|
219
276
|
|
|
220
|
-
The AI Gateway is a
|
|
277
|
+
The AI Gateway is a public beta feature available only on new projects in the `us-east-2` region; it can't be enabled on existing projects. Foundation model access requires a paid Neon plan. Confirm the user's project is a new project in `us-east-2`.
|
|
278
|
+
|
|
279
|
+
### Enabling the gateway: plan and model-catalog gating
|
|
280
|
+
|
|
281
|
+
The AI Gateway is credential-gated rather than a provisioning step, but two plan/beta limits gate it — one blocks provisioning, the other only trims the catalog — and the CLI surfaces each:
|
|
282
|
+
|
|
283
|
+
- **Free plan → provisioning is blocked.** `neon config apply` / `deploy` and `neon checkout` **refuse** to enable the gateway on a Free plan (the gateway can't serve requests there), with a friendly "upgrade to a paid plan, or remove `preview.aiGateway`" error. A dry-run `neon config plan` and `neon env pull` don't provision, so they only **warn**. So: to use the gateway the project's account must be on a paid Neon plan.
|
|
284
|
+
- **Paid plan with a reduced model catalog.** On a paid plan the gateway provisions and serves, but during the beta an account can start with a trimmed catalog — some flagship models (e.g. Anthropic Opus, OpenAI Codex / `*-pro`) are missing from `GET /v1/models`. This is expected; `neon env pull` (and the env pull bundled into `apply` / `deploy` / `checkout`) warns and links the user to their branch's AI Gateway page in the Neon Console (`https://console.neon.tech/app/projects/<project-id>/branches/<branch-id>/ai-gateway`) to request access to more models. Verify what's actually available for the branch by reading `/v1/models` (see the models section above) rather than assuming the full catalog.
|
|
285
|
+
|
|
286
|
+
When helping a user debug "the gateway isn't working" or "a model is missing", use `/v1/models` plus the account's plan to distinguish these two cases — a Free plan blocks provisioning entirely, while a reduced catalog on a paid plan just needs a model-access request.
|
|
221
287
|
|
|
222
288
|
## Neon Documentation
|
|
223
289
|
|
|
@@ -15,7 +15,7 @@ description: >-
|
|
|
15
15
|
|
|
16
16
|
# Neon Functions
|
|
17
17
|
|
|
18
|
-
This is a
|
|
18
|
+
This is a public beta feature and only available in `us-east-2`. Neon Functions are long-running Node.js HTTP handlers deployed onto a Neon branch. Each function gets a public HTTPS URL, runs in the same region as your database, and — if the branch has Postgres — gets `DATABASE_URL` injected automatically. You deploy and manage them through the same Neon CLI, `neon.ts`, and API you already use.
|
|
19
19
|
|
|
20
20
|
Use this skill to help the user define, run locally, deploy, and manage functions next to their database. Deliver a deployed function with its invocation URL, a working local `neon dev` loop, or a precise answer from the official Neon docs.
|
|
21
21
|
|
|
@@ -247,7 +247,7 @@ export default {
|
|
|
247
247
|
|
|
248
248
|
**Hono variant.** If you only need Hono for the HTTP side and are happy driving `ws` yourself, just swap `fetch` in the simple example for `app.fetch` and keep the raw `upgrade` — Hono serves routing/middleware, `ws` serves the socket.
|
|
249
249
|
|
|
250
|
-
To instead declare WebSocket routes _inside_ the Hono app — `app.get("/ws", upgradeWebSocket(...))` with the standard `onOpen`/`onMessage`/`onClose` lifecycle — you need an adapter that bridges Hono's `upgradeWebSocket()` helper to Neon's `upgrade(req, socket, head)`. Hono ships adapters for Cloudflare/Deno/Bun/Node, but **none for Neon**, and the Node one (`@hono/node-ws`) is deprecated and assumes it owns the HTTP server. [references/hono-websockets.md](references/hono-websockets.md) has a small self-contained `createNeonWebSocket(app)` adapter to copy in — it depends only on `hono` and `ws` (no deprecated package; adapted from `@hono/node-ws`, MIT) and returns a ready-to-export `{ fetch, upgrade }` handler. Usage is idiomatic Hono, and because the handshake routes through `app.request`, **auth is just normal route middleware**:
|
|
250
|
+
To instead declare WebSocket routes _inside_ the Hono app — `app.get("/ws", upgradeWebSocket(...))` with the standard `onOpen`/`onMessage`/`onClose` lifecycle — you need an adapter that bridges Hono's `upgradeWebSocket()` helper to Neon's `upgrade(req, socket, head)`. Hono ships adapters for Cloudflare/Deno/Bun/Node, but **none for Neon**, and the Node one (`@hono/node-ws`) is deprecated and assumes it owns the HTTP server. [references/hono-websockets.md](https://neon.com/docs/ai/skills/neon-functions/references/hono-websockets.md) has a small self-contained `createNeonWebSocket(app)` adapter to copy in — it depends only on `hono` and `ws` (no deprecated package; adapted from `@hono/node-ws`, MIT) and returns a ready-to-export `{ fetch, upgrade }` handler. Usage is idiomatic Hono, and because the handshake routes through `app.request`, **auth is just normal route middleware**:
|
|
251
251
|
|
|
252
252
|
```typescript
|
|
253
253
|
// src/index.ts
|
|
@@ -390,7 +390,7 @@ export default {
|
|
|
390
390
|
};
|
|
391
391
|
```
|
|
392
392
|
|
|
393
|
-
The same rules as WebSockets apply. **Heartbeat:** a stream stays open only while bytes flow — Neon's window is 15 minutes ([Timeouts and runtime limits](#timeouts-and-runtime-limits)) but proxies are usually far stricter, so emit a `: ping\n\n` comment every ~25–30s (shown above) to keep idle streams from being dropped. Keep state in Postgres, and fan out across isolates using one of the [sync strategies](#keeping-clients-in-sync-across-isolates-do-not-skip-this) (hold a `Set` of stream controllers and `enqueue` to each). `EventSource` is GET-only and can't set headers, so authenticate with a `?token=` query param or cookie, exactly like the WebSocket case. [references/sse.md](references/sse.md) has the full pattern — Hono variant, cross-isolate fan-out, wire format, client, and caveats.
|
|
393
|
+
The same rules as WebSockets apply. **Heartbeat:** a stream stays open only while bytes flow — Neon's window is 15 minutes ([Timeouts and runtime limits](#timeouts-and-runtime-limits)) but proxies are usually far stricter, so emit a `: ping\n\n` comment every ~25–30s (shown above) to keep idle streams from being dropped. Keep state in Postgres, and fan out across isolates using one of the [sync strategies](#keeping-clients-in-sync-across-isolates-do-not-skip-this) (hold a `Set` of stream controllers and `enqueue` to each). `EventSource` is GET-only and can't set headers, so authenticate with a `?token=` query param or cookie, exactly like the WebSocket case. [references/sse.md](https://neon.com/docs/ai/skills/neon-functions/references/sse.md) has the full pattern — Hono variant, cross-isolate fan-out, wire format, client, and caveats.
|
|
394
394
|
|
|
395
395
|
## MCP servers
|
|
396
396
|
|
|
@@ -404,11 +404,11 @@ app.all("/mcp", async (c) => {
|
|
|
404
404
|
});
|
|
405
405
|
```
|
|
406
406
|
|
|
407
|
-
Because the function's URL is public, **authenticate before connecting the transport** — [Better Auth](https://better-auth.com) covers both OAuth (its MCP plugin makes your app the authorization server so third-party clients self-authorize per the MCP spec) and a simpler API-key / session-JWT check for your own callers. [references/mcp.md](references/mcp.md) has the full pattern — server with Postgres-backed tools via Drizzle, both Better Auth auth options, and testing with `mcporter` / `add-mcp`.
|
|
407
|
+
Because the function's URL is public, **authenticate before connecting the transport** — [Better Auth](https://better-auth.com) covers both OAuth (its MCP plugin makes your app the authorization server so third-party clients self-authorize per the MCP spec) and a simpler API-key / session-JWT check for your own callers. [references/mcp.md](https://neon.com/docs/ai/skills/neon-functions/references/mcp.md) has the full pattern — server with Postgres-backed tools via Drizzle, both Better Auth auth options, and testing with `mcporter` / `add-mcp`.
|
|
408
408
|
|
|
409
409
|
## Integrations and observability
|
|
410
410
|
|
|
411
|
-
A function is a long-lived Node.js process running a web-standard request/response handler, so standard Node integration SDKs work unchanged — initialize them once at module load, gated on an env var so local dev and unconfigured branches stay a no-op, and pass secrets via `--env` or `neon.ts` `env`. For wiring up **Sentry** error monitoring across the HTTP framework, the function runtime, and an agent's own caught/fallback failures (the long-running case Functions target), see [references/sentry.md](references/sentry.md). For running a **Mastra** agent on a function and shipping its traces to a **Mastra Studio (Mastra Cloud)** project for observability, see [references/mastra-studio.md](references/mastra-studio.md).
|
|
411
|
+
A function is a long-lived Node.js process running a web-standard request/response handler, so standard Node integration SDKs work unchanged — initialize them once at module load, gated on an env var so local dev and unconfigured branches stay a no-op, and pass secrets via `--env` or `neon.ts` `env`. For wiring up **Sentry** error monitoring across the HTTP framework, the function runtime, and an agent's own caught/fallback failures (the long-running case Functions target), see [references/sentry.md](https://neon.com/docs/ai/skills/neon-functions/references/sentry.md). For running a **Mastra** agent on a function and shipping its traces to a **Mastra Studio (Mastra Cloud)** project for observability, see [references/mastra-studio.md](https://neon.com/docs/ai/skills/neon-functions/references/mastra-studio.md).
|
|
412
412
|
|
|
413
413
|
## Timeouts and runtime limits
|
|
414
414
|
|
|
@@ -425,7 +425,7 @@ Functions are long-running but **still serverless** — they are a request/respo
|
|
|
425
425
|
|
|
426
426
|
A Neon Function is a great home for an AI agent precisely because it **doesn't time out** the way lambda-style serverless does (15-minute budget, see above). But that advantage disappears the moment you **proxy the agent stream through your web app's backend** — a Next.js route handler, Remix/SvelteKit/Nuxt action, etc. hosted on Vercel, Netlify, Cloudflare, and the like. Those platforms cap serverless/edge execution at short windows (often ~10–60s, sometimes up to ~300s), so a long agent or image/video generation stream gets cut off mid-response even though the Neon Function would happily keep going.
|
|
427
427
|
|
|
428
|
-
**Building the agent itself.** The [Vercel AI SDK](https://ai-sdk.dev) and [Mastra](https://mastra.ai) are the recommended ways to build the agent — point either at the Neon AI Gateway (see the `neon-ai-gateway` skill) for one credential across every model, with no extra provider keys. For a complete AI SDK agent running as a Function (streaming `toUIMessageStreamResponse`, multi-step tool calling next to Postgres, and persisting generated images to Object Storage), see [references/ai-sdk.md](references/ai-sdk.md); for the Mastra equivalent with built-in tracing, see [references/mastra-studio.md](references/mastra-studio.md).
|
|
428
|
+
**Building the agent itself.** The [Vercel AI SDK](https://ai-sdk.dev) and [Mastra](https://mastra.ai) are the recommended ways to build the agent — point either at the Neon AI Gateway (see the `neon-ai-gateway` skill) for one credential across every model, with no extra provider keys. For a complete AI SDK agent running as a Function (streaming `toUIMessageStreamResponse`, multi-step tool calling next to Postgres, and persisting generated images to Object Storage), see [references/ai-sdk.md](https://neon.com/docs/ai/skills/neon-functions/references/ai-sdk.md); for the Mastra equivalent with built-in tracing, see [references/mastra-studio.md](https://neon.com/docs/ai/skills/neon-functions/references/mastra-studio.md).
|
|
429
429
|
|
|
430
430
|
**The fix: call the function directly from the client.** Don't route the long request through your app server.
|
|
431
431
|
|
|
@@ -473,7 +473,7 @@ Pass the JWKS/issuer URL to the function via its `env` (see Environment variable
|
|
|
473
473
|
|
|
474
474
|
## Availability
|
|
475
475
|
|
|
476
|
-
Neon Functions is a
|
|
476
|
+
Neon Functions is a public beta feature available only on new projects in the `us-east-2` region. Confirm the user's Neon project is a new project in `us-east-2`; it can't be enabled on existing projects. Functions usage isn't billed during the public beta.
|
|
477
477
|
|
|
478
478
|
## Neon Documentation
|
|
479
479
|
|
|
@@ -15,7 +15,7 @@ description: >-
|
|
|
15
15
|
|
|
16
16
|
# Neon Object Storage
|
|
17
17
|
|
|
18
|
-
This is a
|
|
18
|
+
This is a public beta feature and only available in `us-east-2`. Neon Object Storage is S3-compatible object storage that branches with your projects: every branch gets its own isolated storage state, so files and database rows stay in sync across dev, preview, staging, and production.
|
|
19
19
|
|
|
20
20
|
Use this skill to help the user store and serve files that branch alongside their database. Deliver a working bucket and upload/download flow, a branch-aware S3 client wired to the injected env vars, or a precise answer from the official Neon docs.
|
|
21
21
|
|
|
@@ -179,7 +179,7 @@ The canonical pattern for pairing storage with the database on a branch: an agen
|
|
|
179
179
|
|
|
180
180
|
## Availability
|
|
181
181
|
|
|
182
|
-
Neon Object Storage is a
|
|
182
|
+
Neon Object Storage is a public beta feature available only on new projects in the `us-east-2` region. Confirm the user's Neon project is a new project in `us-east-2` before proceeding; it can't be enabled on existing projects.
|
|
183
183
|
|
|
184
184
|
## Neon Documentation
|
|
185
185
|
|
|
@@ -78,7 +78,7 @@ If `init` is not suitable, the individual steps can be run non-interactively:
|
|
|
78
78
|
- **MCP server:** `npx -y add-mcp https://mcp.neon.tech/mcp -g -n Neon -y -a <agent-name>`
|
|
79
79
|
- **Agent skill:** `npx skills add neondatabase/agent-skills --skill neon-postgres --agent <agent-name> -y`
|
|
80
80
|
|
|
81
|
-
For full CLI installation options, see https://neon.com/docs/
|
|
81
|
+
For full CLI installation options, see https://neon.com/docs/cli/install.md
|
|
82
82
|
|
|
83
83
|
### Setup Flow
|
|
84
84
|
|
|
@@ -181,16 +181,16 @@ Use this for local development enablement with `npx -y neon@latest init --agent
|
|
|
181
181
|
|
|
182
182
|
| Tool | URL |
|
|
183
183
|
| ---------------- | ----------------------------------------------- |
|
|
184
|
-
| CLI Init Command | https://neon.com/docs/
|
|
184
|
+
| CLI Init Command | https://neon.com/docs/cli/init.md |
|
|
185
185
|
| VSCode Extension | https://neon.com/docs/local/vscode-extension.md |
|
|
186
186
|
| MCP Server | https://neon.com/docs/ai/neon-mcp-server.md |
|
|
187
|
-
| Neon CLI | https://neon.com/docs/
|
|
187
|
+
| Neon CLI | https://neon.com/docs/cli.md |
|
|
188
188
|
|
|
189
189
|
### Neon CLI
|
|
190
190
|
|
|
191
191
|
Use this for terminal-first workflows, scripts, and CI/CD automation with `neon`.
|
|
192
192
|
|
|
193
|
-
Link: https://neon.com/docs/
|
|
193
|
+
Link: https://neon.com/docs/cli.md
|
|
194
194
|
|
|
195
195
|
## Neon Admin API
|
|
196
196
|
|
|
@@ -204,7 +204,7 @@ Link: https://neon.com/docs/reference/api-reference.md
|
|
|
204
204
|
|
|
205
205
|
### Neon TypeScript SDK
|
|
206
206
|
|
|
207
|
-
Use this when implementing typed programmatic control of Neon resources in TypeScript via `@neon/sdk` (the fetch-based, zero-dependency successor to `@neondatabase/api-client`).
|
|
207
|
+
Use this when implementing typed programmatic control of Neon resources in TypeScript via `@neon/sdk` (the fetch-based, zero-dependency successor to `@neondatabase/api-client`). For the full API surface — client config, the `{ data, error }` result model, typed errors, readiness/workflow helpers (`createAndConnect`, `createWithCompute`), pagination, every resource namespace, and the raw layer — see [references/neon-sdk.md](https://neon.com/docs/ai/skills/neon-postgres/references/neon-sdk.md).
|
|
208
208
|
|
|
209
209
|
Link: https://neon.com/docs/reference/typescript-sdk.md
|
|
210
210
|
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# `@neon/sdk` — the TypeScript client for the Neon API
|
|
2
|
+
|
|
3
|
+
`@neon/sdk` is the official TypeScript client for the [Neon API](https://neon.com/docs/reference/api-reference): **Fetch-based, zero-dependency, ESM-only**, generated from Neon's [OpenAPI spec](https://neon.com/api_spec/release/v2.json) with an ergonomic layer on top. It is the successor to [`@neondatabase/api-client`](https://www.npmjs.com/package/@neondatabase/api-client) (axios-based, generated-only). The old client is **not deprecated** and is safe to keep using, but new code should prefer `@neon/sdk`.
|
|
4
|
+
|
|
5
|
+
Use this reference when writing typed, programmatic control of Neon resources in TypeScript — provisioning projects, managing branches/databases/endpoints, transferring projects across orgs, snapshots/restore, consumption metrics, and the beta services (Object Storage, Functions, AI Gateway, scoped credentials).
|
|
6
|
+
|
|
7
|
+
## When to reach for it (vs MCP / CLI)
|
|
8
|
+
|
|
9
|
+
- **Neon MCP server and CLI** are for **local development** — a coding agent in your editor or terminal.
|
|
10
|
+
- **`@neon/sdk`** is for **programmatic integration**: CI/CD pipelines where the CLI isn't enough, non-trivial dev scripts, and full platforms that provision and manage fleets of Neon databases (the same open API behind Replit, Netlify DB, Laravel Cloud, and Vercel's Neon marketplace integration). All it needs is a Neon API key.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @neon/sdk
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Requires Node.js ≥ 20.19, or any runtime with a global `fetch` (Bun, Deno, edge, browser).
|
|
19
|
+
|
|
20
|
+
## Two layers, one package
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { createNeonClient, raw } from "@neon/sdk";
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- **`createNeonClient`** — the high-level ergonomic client: auth once, `{ data, error }` results, typed errors, retries, readiness polling, auto-pagination, and multi-step workflows, organized into resource namespaces (`neon.projects`, `neon.branches`, `neon.postgres`, …).
|
|
27
|
+
- **`raw`** — the full generated 1:1 surface: every endpoint as a standalone, tree-shakeable function (also at the `@neon/sdk/raw` subpath). Speaks the **same** `{ data, error }` / `throwOnError` contract as the ergonomic client.
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { createNeonClient } from "@neon/sdk";
|
|
33
|
+
|
|
34
|
+
const neon = createNeonClient({ apiKey: process.env.NEON_API_KEY! });
|
|
35
|
+
|
|
36
|
+
// Create a project and get a ready-to-use connection string in one call.
|
|
37
|
+
const { data, error } = await neon.projects.createAndConnect({ name: "my-app" });
|
|
38
|
+
if (error) throw error;
|
|
39
|
+
const { project, connectionString } = data;
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Client configuration
|
|
43
|
+
|
|
44
|
+
`createNeonClient(config)`:
|
|
45
|
+
|
|
46
|
+
| Option | Type | Default | Description |
|
|
47
|
+
| --- | --- | --- | --- |
|
|
48
|
+
| `apiKey` | `string \| (() => string \| Promise<string>)` | — (required) | Neon API key, or a function returning it. Sent as a Bearer token. |
|
|
49
|
+
| `throwOnError` | `boolean` | `false` | `true` → methods return the resource directly and **throw** on error. `false` → return `{ data, error }`. **Narrows return types** at the type level. |
|
|
50
|
+
| `waitForReadiness` | `boolean` | `false` | `true` → mutations block until their provisioning `operations` finish, so the returned resource is ready. |
|
|
51
|
+
| `wait` | `{ pollIntervalMs?; timeoutMs? }` | `1000` / `300000` | Readiness poller tuning. |
|
|
52
|
+
| `retries` | `number` | `2` | Automatic retries on always-safe statuses (`423`, `429`, `503`) with backoff. |
|
|
53
|
+
| `orgId` | `string` | — | Default org for project create/list and as the transfer source org. Overridable per call. |
|
|
54
|
+
| `baseUrl` | `string` | `https://console.neon.tech/api/v2` | Override the API base URL. |
|
|
55
|
+
| `fetch` | `typeof fetch` | global `fetch` | Custom fetch (proxies, tests, non-global runtimes). |
|
|
56
|
+
|
|
57
|
+
Every option except `apiKey` is also accepted **per call** via the trailing `options` arg (`{ throwOnError?, waitForReadiness?, signal? }`), overriding the client default.
|
|
58
|
+
|
|
59
|
+
## The result model
|
|
60
|
+
|
|
61
|
+
By default every method resolves to a discriminated `{ data, error }` envelope — no `try/catch`:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const { data, error } = await neon.projects.get("late-frost-12345");
|
|
65
|
+
if (error) return; // error is a typed NeonError union
|
|
66
|
+
data; // narrowed to Project
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Set `throwOnError` (on the client or per call) to get the bare resource and throw instead — the return type narrows accordingly:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const neon = createNeonClient({ apiKey, throwOnError: true });
|
|
73
|
+
const project = await neon.projects.get("…"); // Project (throws)
|
|
74
|
+
const res = await neon.projects.get("…", { throwOnError: false }); // { data, error }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Errors
|
|
78
|
+
|
|
79
|
+
The `error` channel carries a typed hierarchy (all `Error` subclasses with a `kind` discriminant); the same value is thrown when `throwOnError` is set.
|
|
80
|
+
|
|
81
|
+
| Class | `kind` | Notable fields |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| `NeonError` | (base) | `message`, `kind` |
|
|
84
|
+
| `NeonApiError` | `"api"` | `status`, `code`, `requestId`, `response`, `body` |
|
|
85
|
+
| `NeonNotFoundError` | `"not_found"` | 404 — extends `NeonApiError` |
|
|
86
|
+
| `NeonAuthError` | `"auth"` | 401/403 |
|
|
87
|
+
| `NeonRateLimitError` | `"rate_limit"` | 429 (after retries) |
|
|
88
|
+
| `NeonOperationError` | `"operation"` | `operationId`, `status` — an awaited operation failed |
|
|
89
|
+
| `NeonTimeoutError` | `"timeout"` | readiness/wait deadline exceeded |
|
|
90
|
+
| `NeonNetworkError` | `"network"` | transport failure (no response) |
|
|
91
|
+
| `NeonError` | `"client"` | SDK-side errors (e.g. ambiguous connection-string selection) |
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
const { error } = await neon.branches.get(pid, "nope");
|
|
95
|
+
if (error?.kind === "not_found") { /* … */ }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Pagination
|
|
99
|
+
|
|
100
|
+
Cursor-paginated `list()` methods return a lazy `Paginated<T>`:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
const { data: all } = await neon.projects.list().all(); // every page → { data, error }
|
|
104
|
+
const { data: page } = await neon.projects.list().page(); // one page
|
|
105
|
+
for await (const project of neon.projects.list()) { … } // stream; throws on a page error
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Readiness & workflows
|
|
109
|
+
|
|
110
|
+
Neon mutations are asynchronous — they return `operations`. `waitForReadiness` blocks until they settle; the **workflow** methods (`createAndConnect`, `createWithCompute`) default it on and hand back a connection string in one call. The underlying primitive is `neon.operations.waitFor(operations)`.
|
|
111
|
+
|
|
112
|
+
## API surface (ergonomic client)
|
|
113
|
+
|
|
114
|
+
Legend: **[P]** returns `Paginated<T>` · **[W]** workflow (multi-step) · **→void** resolves to `void`.
|
|
115
|
+
|
|
116
|
+
### `neon.projects`
|
|
117
|
+
|
|
118
|
+
| Method | Returns | Notes |
|
|
119
|
+
| --- | --- | --- |
|
|
120
|
+
| `list(query?)` | **[P]** `ProjectListItem` | `{ search?, org_id?, limit? }` |
|
|
121
|
+
| `get(id)` | `Project` | |
|
|
122
|
+
| `create(input?)` | `Project` | `{ name?, region_id?, pg_version?, org_id?, autoscaling_limit_min_cu?, autoscaling_limit_max_cu?, settings? }` |
|
|
123
|
+
| `createAndConnect(input?, { pooled? })` | **[W]** `{ project, connectionString }` | one call + readiness; `pooled` default `true` |
|
|
124
|
+
| `update(id, input)` | `Project` | `{ name?, settings? }` |
|
|
125
|
+
| `delete(id)` | `Project` | |
|
|
126
|
+
| `transfer({ fromOrgId?, toOrgId, projectIds })` | **→void** | `fromOrgId` defaults to client `orgId` |
|
|
127
|
+
| `transferFromUser({ toOrgId, projectIds })` | **→void** | personal account → org |
|
|
128
|
+
| `recover(id)` | `Project` | beta — recover a soft-deleted project |
|
|
129
|
+
| `permissions.list / grant / revoke` | `ProjectPermission`(`[]`) | share a project by email |
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
// Provision a project and get a pooled connection string in one call
|
|
133
|
+
const { data } = await neon.projects.createAndConnect(
|
|
134
|
+
{ name: "tenant-42", region_id: "aws-us-east-1" },
|
|
135
|
+
{ pooled: true },
|
|
136
|
+
); // data: { project, connectionString }
|
|
137
|
+
|
|
138
|
+
// Upgrade path: move projects from a sponsored (free) org to the paid org
|
|
139
|
+
await neon.projects.transfer({
|
|
140
|
+
fromOrgId: sponsoredOrgId, // defaults to the client's `orgId`
|
|
141
|
+
toOrgId: paidOrgId,
|
|
142
|
+
projectIds: ["late-frost-12345"],
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### `neon.branches`
|
|
147
|
+
|
|
148
|
+
| Method | Returns | Notes |
|
|
149
|
+
| --- | --- | --- |
|
|
150
|
+
| `list(projectId, query?)` | **[P]** `Branch` | `{ search?, sort_by?, sort_order?, include_deleted? }` |
|
|
151
|
+
| `get(projectId, branchId)` | `Branch` | |
|
|
152
|
+
| `create(projectId, input?)` | `Branch` | `{ name?, parent_id?, parent_lsn?, parent_timestamp?, protected? }` |
|
|
153
|
+
| `update(projectId, branchId, input)` | `Branch` | `{ name?, protected?, expires_at? }` |
|
|
154
|
+
| `delete(projectId, branchId)` | **→void** | |
|
|
155
|
+
| `createWithCompute(projectId, input, { pooled? })` | **[W]** `{ branch, endpoint, connectionString }` | `input`: `{ name?, parentId?, compute?: { minCu?, maxCu?, suspendTimeoutSeconds? } }` |
|
|
156
|
+
| `getDefault(projectId)` / `setDefault(projectId, branchId)` | `Branch` | resolve/set the default branch |
|
|
157
|
+
| `recover(projectId, branchId)` | `Branch` | beta — recover within the 7-day window |
|
|
158
|
+
| `finalizeRestore(projectId, branchId, { name? }?)` | **→void** | commit a restore previewed with `snapshots.restore` |
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
// Branch off the default branch with its own compute — returns a ready connection string
|
|
162
|
+
const { data: prod } = await neon.branches.getDefault(projectId);
|
|
163
|
+
const { data } = await neon.branches.createWithCompute(projectId, {
|
|
164
|
+
name: "preview/pr-123",
|
|
165
|
+
parentId: prod?.id,
|
|
166
|
+
compute: { minCu: 0.25, maxCu: 2 },
|
|
167
|
+
}); // data: { branch, endpoint, connectionString }
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### `neon.postgres`
|
|
171
|
+
|
|
172
|
+
The Postgres data plane of a branch. `neon.postgres.connectionString(params, options?)` resolves a URI, **auto-selecting** the default branch and the sole role/database when omitted:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
const { data: uri } = await neon.postgres.connectionString({
|
|
176
|
+
projectId, // branchId?, endpointId?, databaseName?, roleName?, pooled? all optional; pooled default true
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Nested namespaces:
|
|
181
|
+
|
|
182
|
+
- **`neon.postgres.endpoints`** — `list / get / create / update / delete`, plus `start` / `suspend` / `restart` and `listByBranch(projectId, branchId)`.
|
|
183
|
+
- **`neon.postgres.roles`** — `list / get / create / delete`, plus `password(...)` (reveals) and `resetPassword(...)` (rotates; result carries the new password).
|
|
184
|
+
- **`neon.postgres.databases`** — `list / get / create / update / delete`.
|
|
185
|
+
- **`neon.postgres.dataApi`** — `get / create / update / delete` the branch's Data API.
|
|
186
|
+
|
|
187
|
+
### Beta services
|
|
188
|
+
|
|
189
|
+
- **`neon.storage`** — branch object storage. `get(projectId, branchId)` → `BranchStorage`; nested `buckets` (`list / create / delete`) and `objects` (`list / get / delete / deleteByPrefix / presign`). Use `presign(..., { operation: "upload" | "download" })` for direct S3-style transfers.
|
|
190
|
+
- **`neon.functions`** — branch Neon Functions. `list` **[P]** `/ get / update / delete`, and `deploy(projectId, branchId, slug, { zip?, runtime?, environment? })` (multipart; poll `get` until `current_deployment.status === "completed"`).
|
|
191
|
+
- **`neon.credentials`** — branch scoped credentials. `list / create / revoke`; secrets (`api_token`, `s3_secret_access_key`) are returned **once** on `create`. Scopes: `storage:read`, `storage:write`, `ai_gateway:invoke`, `functions:invoke`.
|
|
192
|
+
- **`neon.aiGateway`** — `get(projectId, branchId)` → `BranchAiGateway` (404 when the gateway is not enabled on the branch). See the `neon-ai-gateway` skill for calling the gateway itself.
|
|
193
|
+
|
|
194
|
+
### `neon.snapshots`
|
|
195
|
+
|
|
196
|
+
| Method | Returns | Notes |
|
|
197
|
+
| --- | --- | --- |
|
|
198
|
+
| `list(projectId)` | `Snapshot[]` | |
|
|
199
|
+
| `create(projectId, branchId, input?)` | `Snapshot` | `{ name?, timestamp?, lsn?, expiresAt? }` (point-in-time) |
|
|
200
|
+
| `update(projectId, snapshotId, input)` | `Snapshot` | `{ name?, expiresAt? }` — `expiresAt: null` clears the TTL |
|
|
201
|
+
| `delete(projectId, snapshotId)` | **→void** | |
|
|
202
|
+
| `restore(projectId, snapshotId, input?)` | `Branch` | see below |
|
|
203
|
+
| `getSchedule` / `setSchedule(projectId, branchId, …)` | `BackupSchedule` / **→void** | |
|
|
204
|
+
|
|
205
|
+
`restore` input: `{ name?, targetBranchId?, finalize?, preview?, keepOnAbort? }`.
|
|
206
|
+
- Restoring **as a new branch** (no `targetBranchId`) finalizes by default → ready to use.
|
|
207
|
+
- Restoring **onto an existing branch** doesn't finalize by default, so you can preview first.
|
|
208
|
+
- **Transaction-style** `preview`: restores un-finalized, runs your callback, then **finalizes (commit)** on `true` or **deletes the preview branch (abort)** on `false` (unless `keepOnAbort`):
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
await neon.snapshots.restore(projectId, snapshotId, {
|
|
212
|
+
targetBranchId,
|
|
213
|
+
preview: async (branch) => (await checks(branch)) === "ok", // true → commit · false → abort
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### `neon.operations` / `neon.consumption` / `neon.apiKeys` / `neon.regions` / `neon.user` / `neon.auth`
|
|
218
|
+
|
|
219
|
+
- **`operations`** — `list` **[P]** `/ get`, and `waitFor(operations, { pollIntervalMs?, timeoutMs?, signal? })` (the readiness primitive).
|
|
220
|
+
- **`consumption`** — cursor-paginated billing metrics: `perProject`, `perProjectV2`, `perBranchV2` (each takes `{ from, to, granularity, project_ids?, org_id? }`; `perBranchV2` requires `project_ids`). Consumption requires a Scale plan or above.
|
|
221
|
+
- **`apiKeys`** — `list / create(keyName) / revoke`; the created `key` token is shown **once**.
|
|
222
|
+
- **`regions.list()`**, **`user.me()` / `user.organizations()`**.
|
|
223
|
+
- **`auth`** — branch-scoped Neon Auth: `get / create / disable / updateConfig`, plus `oauthProviders`, `trustedDomains`, and `users` sub-resources.
|
|
224
|
+
|
|
225
|
+
## Drop down to the raw client
|
|
226
|
+
|
|
227
|
+
The ergonomic namespaces don't wrap every endpoint. For anything else, `raw` exposes every endpoint 1:1 — pass `neon.client` so the call reuses the client's auth:
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
import { raw } from "@neon/sdk";
|
|
231
|
+
// or, for guaranteed tree-shaking: import { getProjectBranchSchema } from "@neon/sdk/raw";
|
|
232
|
+
|
|
233
|
+
const { data, error } = await raw.getProjectBranchSchema({
|
|
234
|
+
client: neon.client,
|
|
235
|
+
path: { project_id, branch_id },
|
|
236
|
+
query: { db_name: "neondb" }, // db_name is required
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The raw layer speaks the same result contract: `{ data, error }` by default, or pass `throwOnError: true` for the bare resource. All request/response/error **types** are re-exported flat from `@neon/sdk` for `import type { Project, Branch, … }`.
|
|
241
|
+
|
|
242
|
+
Wait on operations from a raw mutation with the readiness primitive:
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
const { data } = await raw.createProjectBranch({
|
|
246
|
+
client: neon.client,
|
|
247
|
+
path: { project_id: projectId },
|
|
248
|
+
body: { branch: { name: "wip" } },
|
|
249
|
+
});
|
|
250
|
+
const { error } = await neon.operations.waitFor(data!.operations, { timeoutMs: 120_000 });
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Migrating from `@neondatabase/api-client`
|
|
254
|
+
|
|
255
|
+
There's no rush — `@neondatabase/api-client` is not being deprecated. When you do move: swap axios-style `try/catch` for the `{ data, error }` envelope (or set `throwOnError: true` to keep throwing), and replace hand-rolled operation polling with `waitForReadiness` / the workflow methods (`createAndConnect`, `createWithCompute`).
|
|
256
|
+
|
|
257
|
+
## Further reading
|
|
258
|
+
|
|
259
|
+
- npm: https://www.npmjs.com/package/@neon/sdk
|
|
260
|
+
- Neon TypeScript SDK docs: https://neon.com/docs/reference/typescript-sdk.md
|
|
261
|
+
- Neon API reference: https://neon.com/docs/reference/api-reference
|
|
262
|
+
- Building a platform on Neon: the `neon-for-agent-platforms` skill (`npx skills add neondatabase/neon-for-agent-platforms`) ships runnable `@neon/sdk` scripts for provisioning, branching, snapshots, project transfer, and consumption metrics.
|
|
@@ -32,7 +32,7 @@ If the request is ambiguous, ask one clarifying question:
|
|
|
32
32
|
Always support both Neon CLI and Neon MCP server. Prefer the tool the user already has installed and authenticated.
|
|
33
33
|
|
|
34
34
|
MCP link: https://neon.com/docs/ai/neon-mcp-server.md
|
|
35
|
-
CLI link: https://neon.com/docs/
|
|
35
|
+
CLI link: https://neon.com/docs/cli/quickstart.md
|
|
36
36
|
|
|
37
37
|
### Selection order
|
|
38
38
|
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stripe-best-practices
|
|
3
3
|
description: >-
|
|
4
|
-
Guides Stripe integration decisions
|
|
4
|
+
Guides Stripe integration decisions across API selection (Checkout Sessions vs
|
|
5
5
|
PaymentIntents), Connect platform setup (Accounts v2, controller properties),
|
|
6
|
-
billing/subscriptions,
|
|
6
|
+
billing/subscriptions, tax and registrations (Stripe Tax, automatic_tax,
|
|
7
|
+
product tax codes), Treasury financial accounts, integration options
|
|
7
8
|
(Checkout, Payment Element), migrating from deprecated Stripe APIs, and
|
|
8
9
|
security best practices (API key management, restricted keys, webhooks,
|
|
9
|
-
OAuth). Use when building, modifying, or reviewing any Stripe integration
|
|
10
|
+
OAuth). Use when building, modifying, or reviewing any Stripe integration,
|
|
10
11
|
including accepting payments, building marketplaces, integrating Stripe,
|
|
11
|
-
processing payments, setting up subscriptions,
|
|
12
|
-
implementing secure key handling.
|
|
12
|
+
processing payments, setting up subscriptions, collecting sales tax, VAT, or
|
|
13
|
+
GST, creating connected accounts, or implementing secure key handling.
|
|
13
14
|
|
|
14
15
|
---
|
|
15
16
|
|
|
16
17
|
Latest Stripe API version: **2026-06-24.dahlia**. Always use the latest API version and SDK unless the user specifies otherwise.
|
|
17
18
|
|
|
18
|
-
If you
|
|
19
|
+
If you don’t have a Stripe account, you can call a CLI command to generate working API keys with no registration required. You can install the Stripe CLI (`npm i -g @stripe/cli`) and run the command `stripe sandbox create` to get started.
|
|
19
20
|
|
|
20
21
|
API key default: Always recommend a [restricted API key (RAK)](https://docs.stripe.com/keys/restricted-api-keys.md) (`rk_` prefix) over a secret key (`sk_` prefix).
|
|
21
22
|
|
|
@@ -37,8 +38,12 @@ Read the relevant reference file before answering any integration question or wr
|
|
|
37
38
|
|
|
38
39
|
## Critical rules
|
|
39
40
|
|
|
41
|
+
- *Before enabling `automatic_tax: { enabled: true }`* (or calculating tax for a custom PaymentIntent), read the [tax reference](references/tax.md) and confirm the user has an active registration. Without one, Stripe calculates and collects no tax while the user believes tax is on (the most common Stripe Tax mistake).
|
|
42
|
+
|
|
40
43
|
- *Never include `payment_method_types` in any Stripe API call*, with one exception: Terminal (in-person payments) integrations must pass `payment_method_types: ['card_present']` on the PaymentIntent. For all other integrations, omit this parameter entirely to enable dynamic payment methods, which enables you to configure payment method settings from the Dashboard and dynamically display the most relevant eligible payment methods to each customer to maximize conversion. To customize which payment methods you accept, use [`payment_method_configurations`](https://docs.stripe.com/payments/payment-method-configurations.md) or `excluded_payment_method_types` instead of `payment_method_types`.
|
|
41
44
|
|
|
45
|
+
- On API version `2026-03-25.dahlia` or later, pass the parameter `integration_identifier` to `checkout.sessions.create` to tag sessions with a custom label for tracking and comparing checkout flows in the Dashboard. The label should include a suffix of 8 random letters.
|
|
46
|
+
|
|
42
47
|
## Key documentation
|
|
43
48
|
|
|
44
49
|
When the user’s request does not clearly fit a single domain above, consult:
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
- When to use Billing APIs
|
|
6
6
|
- Recommended frontend pairing
|
|
7
|
+
- Usage-based billing
|
|
7
8
|
- Traps to avoid
|
|
8
9
|
|
|
9
10
|
## When to use Billing APIs
|
|
@@ -18,6 +19,8 @@ Combine Billing APIs with Stripe Checkout for the payment frontend. Checkout Ses
|
|
|
18
19
|
|
|
19
20
|
For self-service subscription management (upgrades, downgrades, cancellation, payment method updates), recommend the [Customer Portal](https://docs.stripe.com/customer-management/integrate-customer-portal.md).
|
|
20
21
|
|
|
22
|
+
On API version `2026-03-25.dahlia` or later, pass the parameter `integration_identifier` to `checkout.sessions.create` to tag sessions with a custom label for tracking and comparing checkout flows in the Dashboard. The label should include a suffix of 8 random letters.
|
|
23
|
+
|
|
21
24
|
## Usage-based billing
|
|
22
25
|
|
|
23
26
|
**For any new usage-based billing integration, recommend [Metronome](https://docs.stripe.com/billing/usage-based.md) — not the Billing Meters API.** Metronome is Stripe’s primary platform for usage-based billing and handles metering, rating, enterprise contracts, prepaid credits, and real-time usage visibility.
|
|
@@ -44,6 +47,8 @@ Read [Compare basic usage-based billing and Metronome](https://docs.stripe.com/b
|
|
|
44
47
|
- Don’t build manual subscription renewal loops using raw PaymentIntents. Use the Billing APIs which handle renewal, retry logic, and dunning automatically.
|
|
45
48
|
- Don’t use the deprecated `plan` object. Use [Prices](https://docs.stripe.com/api/prices.md) instead.
|
|
46
49
|
- Don’t skip tax setup. See [Collect taxes for recurring payments](https://docs.stripe.com/billing/taxes/collect-taxes.md).
|
|
50
|
+
- Don’t put prices for different tiers or plans on a single product. Instead, create one Product for each plan a customer can choose. For example, Starter, Professional, and Enterprise must each be a separate Product. Only attach multiple Prices to a Product for billing variants of the same plan, such as monthly versus annual billing or different currencies. Avoid placing Prices for different tiers on a single Product. Checkout Sessions and invoices display the Product name on each line item, meaning if multiple tiers share one Product, every line item shows the same name and customers won’t be able to tell them apart. For more information, see [Model your product catalog](https://docs.stripe.com/products-prices/how-products-and-prices-work.md#model-your-catalog).
|
|
51
|
+
- Don’t skip tax setup, and don’t assume enabling `automatic_tax` is enough. Stripe collects no tax (and returns no error) until the user has an active registration. See [Collect taxes for recurring payments](https://docs.stripe.com/billing/taxes/collect-taxes.md).
|
|
47
52
|
- *Never pass `payment_method_types` when creating a subscription Checkout Session.* Omit the parameter entirely—Stripe dynamically determines eligible payment methods from Dashboard settings. Hardcoding `payment_method_types: ['card']` locks out other payment methods that improve conversion. See [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). Correct pattern:
|
|
48
53
|
|
|
49
54
|
```ts
|
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
|
|
13
13
|
## API hierarchy
|
|
14
14
|
|
|
15
|
-
Use the [Checkout Sessions API](https://docs.stripe.com/api/checkout/sessions.md) (`checkout.sessions.create`) for on-session payments. It supports one-time payments and subscriptions and handles
|
|
15
|
+
Use the [Checkout Sessions API](https://docs.stripe.com/api/checkout/sessions.md) (`checkout.sessions.create`) for on-session payments. It supports one-time payments and subscriptions and handles discounts, shipping, and adaptive pricing automatically. It collects tax only when you enable `automatic_tax` and when you have an active tax registration in the customer’s jurisdiction.
|
|
16
16
|
|
|
17
|
-
Use the [PaymentIntents API](https://docs.stripe.com/payments/paymentintents/lifecycle.md) for off-session payments, or when the
|
|
17
|
+
Use the [PaymentIntents API](https://docs.stripe.com/payments/paymentintents/lifecycle.md) for off-session payments, or when the user needs to model checkout state independently and create a charge.
|
|
18
18
|
|
|
19
19
|
**Integrations should only use Checkout Sessions, PaymentIntents, SetupIntents, or higher-level solutions (Invoicing, Payment Links, subscription APIs).**
|
|
20
20
|
|
|
21
|
+
On API version `2026-03-25.dahlia` or later, pass the parameter `integration_identifier` to `checkout.sessions.create` to tag sessions with a custom label for tracking and comparing checkout flows in the Dashboard. The label should include a suffix of 8 random letters.
|
|
22
|
+
|
|
21
23
|
## Integration surfaces
|
|
22
24
|
|
|
23
25
|
Prioritize Stripe-hosted or embedded Checkout where possible. Use in this order of preference:
|