vybekiit 0.7.4 → 0.7.7
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 +10483 -1704
- package/dist/global-skills/aws-cdk/SKILL.md +2 -1
- package/dist/global-skills/aws-cloudformation/SKILL.md +2 -1
- package/dist/global-skills/aws-serverless/SKILL.md +45 -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 +92 -619
- package/dist/global-skills/claimable-postgres/SKILL.md +60 -49
- package/dist/global-skills/design-my-data/SKILL.md +2 -0
- package/dist/global-skills/eas-app-stores/SKILL.md +8 -0
- package/dist/global-skills/eas-app-stores/references/play-store.md +2 -0
- package/dist/global-skills/eas-hosting/SKILL.md +8 -0
- package/dist/global-skills/eas-observe/SKILL.md +30 -8
- package/dist/global-skills/eas-observe/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-observe/references/metrics.md +54 -3
- package/dist/global-skills/eas-observe/references/queries.md +78 -17
- package/dist/global-skills/eas-observe/references/setup.md +164 -5
- package/dist/global-skills/eas-observe/references/third-party.md +136 -0
- package/dist/global-skills/eas-simulator/SKILL.md +63 -11
- package/dist/global-skills/eas-simulator/references/controllers.md +21 -2
- package/dist/global-skills/eas-simulator/references/run-your-app.md +16 -11
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -5
- package/dist/global-skills/eas-update-insights/SKILL.md +8 -0
- package/dist/global-skills/eas-workflows/SKILL.md +15 -10
- package/dist/global-skills/eas-workflows/scripts/package.json +2 -7
- 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/expo-animation/LICENSE +21 -0
- package/dist/global-skills/expo-animation/RECIPES.md +385 -0
- package/dist/global-skills/expo-animation/SKILL.md +267 -0
- package/dist/global-skills/expo-animation/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-app-clip/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +53 -4
- package/dist/global-skills/expo-data-fetching/SKILL.md +8 -0
- package/dist/global-skills/expo-design-system/SKILL.md +356 -0
- package/dist/global-skills/expo-design-system/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-design-system/references/audit.md +185 -0
- package/dist/global-skills/expo-dev-client/SKILL.md +8 -0
- package/dist/global-skills/expo-dom/SKILL.md +8 -0
- package/dist/global-skills/expo-examples/SKILL.md +8 -0
- package/dist/global-skills/expo-migrate-module/SKILL.md +113 -0
- package/dist/global-skills/expo-migrate-module/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-migrate-module/references/compatibility.md +73 -0
- package/dist/global-skills/expo-migrate-module/references/example.md +212 -0
- package/dist/global-skills/expo-migrate-module/references/migration-map.md +306 -0
- package/dist/global-skills/expo-module/SKILL.md +11 -1
- package/dist/global-skills/expo-native-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-project-structure/SKILL.md +114 -0
- package/dist/global-skills/expo-project-structure/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-router/SKILL.md +8 -0
- package/dist/global-skills/expo-skill-feedback/SKILL.md +66 -33
- package/dist/global-skills/expo-skill-feedback/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-tailwind-setup/SKILL.md +8 -0
- package/dist/global-skills/expo-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-upgrade/SKILL.md +15 -1
- package/dist/global-skills/expo-web-to-native/SKILL.md +8 -0
- package/dist/global-skills/extension-to-functions-codebase/SKILL.md +129 -0
- package/dist/global-skills/extension-to-functions-codebase/references/configuration-migration.md +161 -0
- package/dist/global-skills/extension-to-functions-codebase/references/destructuring-shim.md +122 -0
- package/dist/global-skills/extension-to-functions-codebase/references/signature-mapping.md +84 -0
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +61 -19
- package/dist/global-skills/firebase-ai-logic-basics/references/flutter_setup.md +6 -3
- package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-auth-basics/SKILL.md +4 -2
- package/dist/global-skills/firebase-basics/SKILL.md +5 -5
- package/dist/global-skills/firebase-crashlytics/SKILL.md +2 -0
- package/dist/global-skills/firebase-data-connect/SKILL.md +2 -0
- package/dist/global-skills/firebase-firestore/SKILL.md +3 -6
- package/dist/global-skills/firebase-hosting-basics/SKILL.md +4 -1
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +4 -1
- package/dist/global-skills/harden/SKILL.md +2 -1
- package/dist/global-skills/instrument-feature-flags/SKILL.md +1 -0
- package/dist/global-skills/instrument-feature-flags/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/android.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/api.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/best-practices.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/django.md +38 -5
- package/dist/global-skills/instrument-feature-flags/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-feature-flags/references/elixir.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/flask.md +17 -5
- package/dist/global-skills/instrument-feature-flags/references/flutter.md +7 -5
- package/dist/global-skills/instrument-feature-flags/references/go.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ios.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/java.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/laravel.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/next-js.md +74 -8
- package/dist/global-skills/instrument-feature-flags/references/nodejs.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/php.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/python.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react-native.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/rust.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/usage.md +41 -4
- package/dist/global-skills/instrument-feature-flags/references/web.md +7 -5
- package/dist/global-skills/instrument-product-analytics/SKILL.md +2 -1
- package/dist/global-skills/instrument-product-analytics/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +12 -14
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +25 -21
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-django.md +75 -55
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-fastapi.md +3 -6
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-flask.md +26 -16
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-3-6.md +8 -5
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-4.md +4 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-framework.md +3 -3
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +8 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-tanstack-start.md +20 -8
- package/dist/global-skills/instrument-product-analytics/references/android.md +46 -4
- package/dist/global-skills/instrument-product-analytics/references/angular.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/astro.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +7 -4
- package/dist/global-skills/instrument-product-analytics/references/django.md +38 -5
- package/dist/global-skills/instrument-product-analytics/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-product-analytics/references/elixir.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/flask.md +17 -5
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +49 -4
- package/dist/global-skills/instrument-product-analytics/references/go.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/identify-users.md +38 -7
- package/dist/global-skills/instrument-product-analytics/references/ios.md +14 -4
- package/dist/global-skills/instrument-product-analytics/references/laravel.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/next-js.md +74 -8
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +39 -7
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +40 -4
- package/dist/global-skills/instrument-product-analytics/references/php.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +21 -17
- package/dist/global-skills/instrument-product-analytics/references/python.md +15 -5
- package/dist/global-skills/instrument-product-analytics/references/react-native.md +41 -7
- package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/svelte.md +42 -6
- package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +31 -7
- package/dist/global-skills/instrument-product-analytics/references/usage.md +41 -4
- package/dist/global-skills/instrument-product-analytics/references/vue-js.md +42 -6
- package/dist/global-skills/manifest.json +6 -1
- package/dist/global-skills/neon/SKILL.md +235 -121
- package/dist/global-skills/neon-ai-gateway/SKILL.md +95 -16
- package/dist/global-skills/neon-functions/SKILL.md +242 -152
- package/dist/global-skills/neon-functions/references/ai-sdk.md +9 -3
- package/dist/global-skills/neon-functions/references/mastra-studio.md +1 -1
- package/dist/global-skills/neon-functions/references/mcp.md +13 -4
- package/dist/global-skills/neon-functions/references/sentry.md +165 -52
- package/dist/global-skills/neon-functions/references/sse.md +23 -6
- package/dist/global-skills/neon-object-storage/SKILL.md +40 -16
- package/dist/global-skills/neon-postgres/SKILL.md +63 -262
- package/dist/global-skills/neon-postgres-branches/SKILL.md +61 -50
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +22 -3
- package/dist/global-skills/resend/SKILL.md +6 -6
- package/dist/global-skills/resend/references/automations.md +2 -2
- package/dist/global-skills/resend/references/broadcasts.md +11 -3
- package/dist/global-skills/resend/references/domains.md +25 -3
- package/dist/global-skills/resend/references/installation.md +7 -7
- package/dist/global-skills/setup-payments/SKILL.md +4 -5
- package/dist/global-skills/stripe-best-practices/SKILL.md +32 -7
- package/dist/global-skills/stripe-best-practices/references/billing.md +11 -1
- package/dist/global-skills/stripe-best-practices/references/payments.md +23 -2
- package/dist/global-skills/stripe-best-practices/references/security.md +21 -11
- package/dist/global-skills/stripe-best-practices/references/tax.md +116 -11
- package/dist/global-skills/supabase/CHANGELOG.md +25 -0
- package/dist/global-skills/supabase/SKILL.md +5 -1
- package/dist/global-skills/supabase-postgres-best-practices/CHANGELOG.md +30 -0
- package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +1 -1
- package/dist/global-skills/use-kit-mcp/SKILL.md +5 -5
- package/dist/global-skills/use-railway/SKILL.md +4 -4
- package/dist/global-skills/use-railway/references/iac.md +206 -57
- package/dist/global-skills/use-railway/scripts/railway-api.sh +7 -2
- package/dist/global-skills/xcode-project-setup/SKILL.md +2 -0
- package/package.json +12 -9
- package/LICENSE.md +0 -47
- package/dist/global-skills/eas-workflows/scripts/validate.js +0 -84
- package/dist/global-skills/expo-skill-feedback/scripts/skill-feedback.cjs +0 -118
- package/dist/global-skills/neon-functions/references/hono-websockets.md +0 -145
|
@@ -4,7 +4,7 @@ description: Use when working with the Resend email API — sending transactiona
|
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: resend
|
|
7
|
-
version: "3.5.
|
|
7
|
+
version: "3.5.2"
|
|
8
8
|
homepage: https://resend.com/agent-skills
|
|
9
9
|
source: https://github.com/resend/resend-skills
|
|
10
10
|
openclaw:
|
|
@@ -180,12 +180,12 @@ Always install the latest SDK version. These are the minimum versions for full f
|
|
|
180
180
|
| Language | Package | Min Version | Install |
|
|
181
181
|
|----------|---------|-------------|---------|
|
|
182
182
|
| Node.js | `resend` | >= 6.14.0 | `npm install resend` |
|
|
183
|
-
| Python | `resend` | >= 2.
|
|
184
|
-
| Go | `resend-go/v3` | >= 3.
|
|
185
|
-
| Ruby | `resend` | >= 1.
|
|
183
|
+
| Python | `resend` | >= 2.34.0 | `pip install resend` |
|
|
184
|
+
| Go | `resend-go/v3` | >= 3.11.0 | `go get github.com/resend/resend-go/v3` |
|
|
185
|
+
| Ruby | `resend` | >= 1.6.0 | `gem install resend` |
|
|
186
186
|
| PHP | `resend/resend-php` | >= 1.1.0 | `composer require resend/resend-php` |
|
|
187
|
-
| Rust | `resend-rs` | >= 0.
|
|
188
|
-
| Java | `resend-java` | >= 4.
|
|
187
|
+
| Rust | `resend-rs` | >= 0.26.1 | `cargo add resend-rs` |
|
|
188
|
+
| Java | `resend-java` | >= 4.16.0 | See [installation.md](references/installation.md) |
|
|
189
189
|
| .NET | `Resend` | >= 0.2.1 | `dotnet add package Resend` |
|
|
190
190
|
|
|
191
191
|
> **If the project already has a Resend SDK installed**, check the version and upgrade if it's below the minimum. Older SDKs may be missing `webhooks.verify()`, `emails.receiving.get()`, or `domains.claims.*`.
|
|
@@ -52,7 +52,7 @@ Groups: `{ "type": "and" | "or", "rules": [...] }` for nesting.
|
|
|
52
52
|
|
|
53
53
|
Supported operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `starts_with`, `ends_with`, `exists`, `is_empty`. The `exists` and `is_empty` operators require no `value`.
|
|
54
54
|
|
|
55
|
-
For `condition` steps, fields
|
|
55
|
+
For `condition` steps, fields use the `contact.*`, `event.*`, or `wait_events.*` namespaces (e.g. `contact.properties.plan`). For `filter_rule` in `wait_for_event`, fields use `event.*` or `contact.*` (e.g. `event.status`).
|
|
56
56
|
|
|
57
57
|
### Connections
|
|
58
58
|
|
|
@@ -149,7 +149,7 @@ const { data, error } = await resend.automations.create({
|
|
|
149
149
|
{
|
|
150
150
|
key: 'check_plan',
|
|
151
151
|
type: 'condition',
|
|
152
|
-
config: { type: 'rule', field: 'properties.plan', operator: '
|
|
152
|
+
config: { type: 'rule', field: 'contact.properties.plan', operator: 'eq', value: 'pro' },
|
|
153
153
|
},
|
|
154
154
|
{ key: 'send_pro', type: 'send_email', config: { template: { id: 'tmpl_pro' }, from: 'Acme <hello@acme.com>' } },
|
|
155
155
|
{ key: 'send_free', type: 'send_email', config: { template: { id: 'tmpl_free' }, from: 'Acme <hello@acme.com>' } },
|
|
@@ -10,6 +10,7 @@ Send emails to audience segments. Broadcasts follow a two-step lifecycle: **crea
|
|
|
10
10
|
| Get | `resend.broadcasts.get(id)` | `resend.Broadcasts.get(id)` |
|
|
11
11
|
| List | `resend.broadcasts.list(params)` | `resend.Broadcasts.list(params)` |
|
|
12
12
|
| Send | `resend.broadcasts.send(id, params?)` | `resend.Broadcasts.send(params)` |
|
|
13
|
+
| Cancel | `resend.broadcasts.cancel(id)` | `resend.Broadcasts.cancel(id)` |
|
|
13
14
|
| Update | `resend.broadcasts.update(id, params)` | `resend.Broadcasts.update(params)` |
|
|
14
15
|
| Delete | `resend.broadcasts.remove(id)` | `resend.Broadcasts.remove(id)` |
|
|
15
16
|
|
|
@@ -66,7 +67,7 @@ const { data, error } = await resend.broadcasts.create({
|
|
|
66
67
|
});
|
|
67
68
|
```
|
|
68
69
|
|
|
69
|
-
## Get, List, Update, Delete
|
|
70
|
+
## Get, List, Update, Cancel, Delete
|
|
70
71
|
|
|
71
72
|
```typescript
|
|
72
73
|
// Get
|
|
@@ -80,7 +81,12 @@ const { data, error } = await resend.broadcasts.update('bc_abc123', {
|
|
|
80
81
|
subject: 'Updated subject line',
|
|
81
82
|
});
|
|
82
83
|
|
|
83
|
-
//
|
|
84
|
+
// Cancel a queued or scheduled broadcast — stops a queued send mid-flight, or
|
|
85
|
+
// reverts a scheduled one to draft. Does not remove the broadcast.
|
|
86
|
+
const { data, error } = await resend.broadcasts.cancel('bc_abc123');
|
|
87
|
+
|
|
88
|
+
// Delete — draft or scheduled only (deleting a scheduled broadcast also
|
|
89
|
+
// cancels its delivery). Sent broadcasts cannot be deleted.
|
|
84
90
|
const { data, error } = await resend.broadcasts.remove('bc_abc123');
|
|
85
91
|
```
|
|
86
92
|
|
|
@@ -117,7 +123,9 @@ Use triple-mustache with a pipe for fallbacks: `{{{PROPERTY_KEY|fallback}}}`
|
|
|
117
123
|
|---------|-----|
|
|
118
124
|
| Expecting `create` to send the broadcast | `create` makes a draft. Call `send` separately, or pass `send: true` |
|
|
119
125
|
| Calling `.delete()` instead of `.remove()` | Node.js SDK uses `.remove()` for all delete operations |
|
|
120
|
-
| Deleting a sent
|
|
126
|
+
| Deleting a sent broadcast | Only draft or scheduled broadcasts can be deleted |
|
|
127
|
+
| Cancelling a draft or sent broadcast | Only queued or scheduled broadcasts can be cancelled |
|
|
128
|
+
| Using `.remove()` when you just want to stop delivery | `.cancel()` stops/reverts without deleting the broadcast; `.remove()` deletes it entirely |
|
|
121
129
|
| Missing `segmentId` | Required — broadcasts target segments, not all contacts |
|
|
122
130
|
| Missing unsubscribe link | Include `{{{RESEND_UNSUBSCRIBE_URL}}}` in HTML |
|
|
123
131
|
| `{{VAR}}` instead of `{{{VAR}}}` | Triple braces required for variable interpolation |
|
|
@@ -25,7 +25,7 @@ Create → Add DNS records → Verify → Poll status → Send
|
|
|
25
25
|
|
|
26
26
|
`resend.Domains.create/get/list/update/remove/verify` — same operations with snake_case params (e.g., `custom_return_path`, `open_tracking`, `click_tracking`).
|
|
27
27
|
|
|
28
|
-
> **Claiming a domain another Resend account already verified?** See [Claim a Domain](#claim-a-domain) — Node
|
|
28
|
+
> **Claiming a domain another Resend account already verified?** See [Claim a Domain](#claim-a-domain) — available in the Node.js, Python, Ruby, Go, Rust, and Java SDKs, and the CLI (`resend domains claim`).
|
|
29
29
|
|
|
30
30
|
## Use a Subdomain
|
|
31
31
|
|
|
@@ -108,7 +108,7 @@ Claiming takes over a domain **another Resend account has already verified**. Th
|
|
|
108
108
|
Claim → Add TXT proof to DNS → Verify claim → (completed) → Update DKIM in DNS → Verify domain → Send
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
Claim methods are available
|
|
111
|
+
Claim methods are available in the **Node.js** (`resend >= 6.14.0`), **Python** (`resend >= 2.34.0`), **Ruby** (`resend >= 1.6.0`), **Go** (`resend-go/v3 >= 3.11.0`), **Rust** (`resend-rs >= 0.26.1`), and **Java** (`resend-java >= 4.16.0`) SDKs, plus the **CLI** (`resend domains claim`) and REST API. Not yet in the PHP or .NET SDKs.
|
|
112
112
|
|
|
113
113
|
| Operation | Method | Notes |
|
|
114
114
|
|-----------|--------|-------|
|
|
@@ -116,6 +116,8 @@ Claim methods are available via the **Node SDK** (`resend >= 6.14.0`) and the **
|
|
|
116
116
|
| Get claim | `resend.domains.claims.get(domainId)` | Latest claim for the placeholder domain — poll `status` |
|
|
117
117
|
| Verify claim | `resend.domains.claims.verify(domainId)` | Triggers async DNS proof + transfer (not synchronous) |
|
|
118
118
|
|
|
119
|
+
Method naming per SDK: Python `resend.Domains.Claims.create/get/verify` (async: `create_async/get_async/verify_async`), Ruby `Resend::Domains::Claims.create/get/verify`, Go `client.DomainClaims.Create(&CreateDomainClaimRequest{...})/Get(domainId)/Verify(domainId)` (+ `*WithContext`), Rust `domains.claim(opts)/get_claim(id)/verify_claim(id)`, Java `resend.domains().claims().create(ClaimDomainOptions)/get(id)/verify(id)`.
|
|
120
|
+
|
|
119
121
|
```typescript
|
|
120
122
|
// 1. Start the claim — returns the placeholder domain id + TXT record to add
|
|
121
123
|
const { data: claim, error } = await resend.domains.claims.create({
|
|
@@ -142,6 +144,26 @@ console.log(domain.records); // add these to DNS, then:
|
|
|
142
144
|
await resend.domains.verify(claim.domain_id);
|
|
143
145
|
```
|
|
144
146
|
|
|
147
|
+
```python
|
|
148
|
+
# 1. Start the claim — returns the placeholder domain id + TXT record to add
|
|
149
|
+
claim = resend.Domains.Claims.create({"name": "send.acme.com"})
|
|
150
|
+
print(claim["domain_id"]) # placeholder domain id for later calls
|
|
151
|
+
print(claim["record"]) # {type: 'TXT', name, value, ttl} — add to DNS
|
|
152
|
+
|
|
153
|
+
# 2. After adding the TXT record, trigger verification
|
|
154
|
+
resend.Domains.Claims.verify(domain_id=claim["domain_id"])
|
|
155
|
+
|
|
156
|
+
# 3. Poll until the claim status is 'completed'
|
|
157
|
+
latest = resend.Domains.Claims.get(domain_id=claim["domain_id"])
|
|
158
|
+
print(latest["status"]) # 'pending' | 'verified' | 'completed' | 'blocked' | ...
|
|
159
|
+
|
|
160
|
+
# 4. Once 'completed', fetch the transferred domain's NEW DKIM records,
|
|
161
|
+
# update DNS, then verify the domain itself.
|
|
162
|
+
domain = resend.Domains.get(claim["domain_id"])
|
|
163
|
+
print(domain["records"]) # add these to DNS, then:
|
|
164
|
+
resend.Domains.verify(claim["domain_id"])
|
|
165
|
+
```
|
|
166
|
+
|
|
145
167
|
A `blocked` status means a safety check failed — inspect `blocked_reason` (`grace_period`, `recent_owner_activity`, `pending_scheduled_emails`).
|
|
146
168
|
|
|
147
169
|
## Parameter Reference
|
|
@@ -176,4 +198,4 @@ A `blocked` status means a safety check failed — inspect `blocked_reason` (`gr
|
|
|
176
198
|
| Reusing the old account's DNS records after a claim | A claim issues **new DKIM keys** — fetch the transferred domain with `domains.get()`, update DNS, then `domains.verify()` |
|
|
177
199
|
| Treating the claim as done at `completed` | `completed` only means the transfer finished — the domain still needs its new DKIM records in DNS and a `domains.verify()` to send |
|
|
178
200
|
| Expecting `claims.verify()` to be synchronous | It triggers an async DNS proof + transfer — poll `claims.get()` for `status` |
|
|
179
|
-
| Looking for a claim method in
|
|
201
|
+
| Looking for a claim method in PHP or .NET | Claims are in the Node.js, Python, Ruby, Go, Rust, and Java SDKs (plus CLI and REST API) — PHP/.NET don't support them yet |
|
|
@@ -9,12 +9,12 @@ These are the minimum versions required for full functionality (sending, receivi
|
|
|
9
9
|
| Language | Package | Min Version | Install |
|
|
10
10
|
|----------|---------|-------------|---------|
|
|
11
11
|
| Node.js | `resend` | >= 6.14.0 | `npm install resend` |
|
|
12
|
-
| Python | `resend` | >= 2.
|
|
13
|
-
| Go | `resend-go/v3` | >= 3.
|
|
14
|
-
| Ruby | `resend` | >= 1.
|
|
12
|
+
| Python | `resend` | >= 2.34.0 | `pip install resend` |
|
|
13
|
+
| Go | `resend-go/v3` | >= 3.11.0 | `go get github.com/resend/resend-go/v3` |
|
|
14
|
+
| Ruby | `resend` | >= 1.6.0 | `gem install resend` |
|
|
15
15
|
| PHP | `resend/resend-php` | >= 1.1.0 | `composer require resend/resend-php` |
|
|
16
|
-
| Rust | `resend-rs` | >= 0.
|
|
17
|
-
| Java | `resend-java` | >= 4.
|
|
16
|
+
| Rust | `resend-rs` | >= 0.26.1 | `cargo add resend-rs` |
|
|
17
|
+
| Java | `resend-java` | >= 4.16.0 | See [Maven/Gradle](#java) below |
|
|
18
18
|
| .NET | `Resend` | >= 0.2.1 | `dotnet add package Resend` |
|
|
19
19
|
|
|
20
20
|
> **If the project already has a Resend SDK installed**, check the version and upgrade if it's below the minimum. Older SDKs may be missing `webhooks.verify()`, `emails.receiving.get()`, or `domains.claims.*`, which power webhook security, inbound email, and domain claiming.
|
|
@@ -90,7 +90,7 @@ cargo add tokio -F macros,rt-multi-thread
|
|
|
90
90
|
|
|
91
91
|
Gradle:
|
|
92
92
|
```gradle
|
|
93
|
-
implementation 'com.resend:resend-java:4.
|
|
93
|
+
implementation 'com.resend:resend-java:4.16.0'
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
Maven:
|
|
@@ -98,7 +98,7 @@ Maven:
|
|
|
98
98
|
<dependency>
|
|
99
99
|
<groupId>com.resend</groupId>
|
|
100
100
|
<artifactId>resend-java</artifactId>
|
|
101
|
-
<version>4.
|
|
101
|
+
<version>4.16.0</version>
|
|
102
102
|
</dependency>
|
|
103
103
|
```
|
|
104
104
|
|
|
@@ -38,11 +38,10 @@ translate every error · celebrate. You wire all the code; the builder only sign
|
|
|
38
38
|
1. **Explain the plan in one line.** *"I'll connect a payment service so you can charge people. I'll do
|
|
39
39
|
the setup — you'll sign in once when I ask."* (Never name Lemon Squeezy, Stripe, or PayPal.)
|
|
40
40
|
|
|
41
|
-
2. **Lemon Squeezy (default) — sign-in only.**
|
|
42
|
-
- Run `vybekiit-automate ls
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
- Run `vybekiit-automate ls setup --json` with name, price, mode, webhook URL from the conversation.
|
|
41
|
+
2. **Lemon Squeezy (default) — sign-in only when needed.**
|
|
42
|
+
- Run `vybekiit-automate ls setup --json …` (or wizard mode without `--json`).
|
|
43
|
+
- If Lemon Squeezy shows a sign-in screen, the automation **waits** until the builder completes login in the browser, then continues — no separate standby step required.
|
|
44
|
+
- Optional pre-check: `vybekiit-automate ls standby` opens the dashboard and waits the same way.
|
|
46
45
|
- Write JSON output to `.env` (`LEMONSQUEEZY_STORE_ID`, variant ID, API key, webhook secret).
|
|
47
46
|
**Verify:** values saved; product exists in test mode.
|
|
48
47
|
|
|
@@ -1,21 +1,38 @@
|
|
|
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
|
-
Latest Stripe API version: **2026-
|
|
17
|
+
Latest Stripe API version: **2026-07-29.dahlia**. Always use the latest API version and SDK unless the user specifies otherwise.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
Latest SDK versions:
|
|
20
|
+
|
|
21
|
+
| Language | Latest version |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| Ruby | 19.4.0 |
|
|
24
|
+
| Python | 15.4.0 |
|
|
25
|
+
| Node.js | 22.4.0 |
|
|
26
|
+
| PHP | 21.1.0 |
|
|
27
|
+
| Java | 33.2.0 |
|
|
28
|
+
| Go | 86.2.0 |
|
|
29
|
+
| .NET | 52.2.0 |
|
|
30
|
+
|
|
31
|
+
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.
|
|
32
|
+
|
|
33
|
+
If `stripe sandbox create` is used, don’t use MCP.
|
|
34
|
+
|
|
35
|
+
If you try to use MCP after running sandbox creation, first make sure `stripe sandbox claim` is run. Use `stripe whoami --format json` for CLI auth checks; do not run `stripe config --list`.
|
|
19
36
|
|
|
20
37
|
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
38
|
|
|
@@ -37,8 +54,16 @@ Read the relevant reference file before answering any integration question or wr
|
|
|
37
54
|
|
|
38
55
|
## Critical rules
|
|
39
56
|
|
|
57
|
+
- *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).
|
|
58
|
+
|
|
40
59
|
- *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
60
|
|
|
61
|
+
- *Never present webhooks as optional.* We recommend webhooks for every payment integration and they’re required for subscriptions and asynchronous payment methods. Fulfillment belongs in a handler for both `checkout.session.completed` and `checkout.session.async_payment_succeeded` (gated on `payment_status`), not the success page. See <references/payments.md>.
|
|
62
|
+
|
|
63
|
+
- 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.
|
|
64
|
+
|
|
65
|
+
- *Always instantiate a `StripeClient` and call methods on that instance.* Do **not** use the deprecated global/module-level API key pattern (`stripe.api_key = …`, `Stripe.setApiKey`, `stripe.Key = …`, `StripeConfiguration.ApiKey = …`). The global pattern is deprecated in all current SDKs.
|
|
66
|
+
|
|
42
67
|
## Key documentation
|
|
43
68
|
|
|
44
69
|
When the user’s request does not clearly fit a single domain above, consult:
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
- When to use Billing APIs
|
|
6
6
|
- Recommended frontend pairing
|
|
7
|
+
- Usage-based billing
|
|
8
|
+
- Tax
|
|
7
9
|
- Traps to avoid
|
|
8
10
|
|
|
9
11
|
## When to use Billing APIs
|
|
@@ -18,6 +20,8 @@ Combine Billing APIs with Stripe Checkout for the payment frontend. Checkout Ses
|
|
|
18
20
|
|
|
19
21
|
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
22
|
|
|
23
|
+
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.
|
|
24
|
+
|
|
21
25
|
## Usage-based billing
|
|
22
26
|
|
|
23
27
|
**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.
|
|
@@ -39,11 +43,17 @@ Use the following routing logic:
|
|
|
39
43
|
|
|
40
44
|
Read [Compare basic usage-based billing and Metronome](https://docs.stripe.com/billing/subscriptions/usage-based/compare-metronome.md) for a full feature comparison. Read [Get started with Metronome](https://docs.stripe.com/billing/usage-based.md) to begin a Metronome integration.
|
|
41
45
|
|
|
46
|
+
## Tax
|
|
47
|
+
|
|
48
|
+
**When answering any Billing setup or subscription question, always include a brief Stripe Tax note before finishing your response.** Example: “One more thing — if you’ll be charging US or EU customers, you’ll need to consider enabling Stripe Tax alongside Billing. See [Collect taxes for recurring payments](https://docs.stripe.com/billing/taxes/collect-taxes.md) for the setup steps.” Don’t wait for the user to ask about sales tax. Read the Stripe Tax skill reference before enabling `automatic_tax`.
|
|
49
|
+
|
|
42
50
|
## Traps to avoid
|
|
43
51
|
|
|
52
|
+
- Don’t call a subscription integration complete without a webhook handler for the subscription lifecycle events (`customer.subscription.*`, `invoice.paid`, `invoice.payment_failed`). Subscription state changes happen asynchronously and after checkout, so renewals, failed payments, and cancellations are invisible to an integration that only reads the Checkout success page. Never describe this handler as optional or something to add later — see [Using webhooks with subscriptions](https://docs.stripe.com/billing/subscriptions/webhooks.md).
|
|
44
53
|
- Don’t build manual subscription renewal loops using raw PaymentIntents. Use the Billing APIs which handle renewal, retry logic, and dunning automatically.
|
|
45
54
|
- Don’t use the deprecated `plan` object. Use [Prices](https://docs.stripe.com/api/prices.md) instead.
|
|
46
|
-
- Don’t
|
|
55
|
+
- 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).
|
|
56
|
+
- 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
57
|
- *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
58
|
|
|
49
59
|
```ts
|
|
@@ -6,18 +6,21 @@
|
|
|
6
6
|
- Integration surfaces
|
|
7
7
|
- Payment Element guidance
|
|
8
8
|
- Saving payment methods
|
|
9
|
+
- Webhooks and fulfillment
|
|
9
10
|
- Dynamic payment methods
|
|
10
11
|
- Deprecated APIs and migration paths
|
|
11
12
|
- PCI compliance
|
|
12
13
|
|
|
13
14
|
## API hierarchy
|
|
14
15
|
|
|
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
|
|
16
|
+
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
17
|
|
|
17
|
-
Use the [PaymentIntents API](https://docs.stripe.com/payments/paymentintents/lifecycle.md) for off-session payments, or when the
|
|
18
|
+
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
19
|
|
|
19
20
|
**Integrations should only use Checkout Sessions, PaymentIntents, SetupIntents, or higher-level solutions (Invoicing, Payment Links, subscription APIs).**
|
|
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
|
## Integration surfaces
|
|
22
25
|
|
|
23
26
|
Prioritize Stripe-hosted or embedded Checkout where possible. Use in this order of preference:
|
|
@@ -39,6 +42,24 @@ Use the [Setup Intents API](https://docs.stripe.com/api/setup_intents.md) to sav
|
|
|
39
42
|
|
|
40
43
|
**Traps to avoid:** Don’t use the Sources API to save cards to customers. The Sources API is deprecated — Setup Intents is the correct approach.
|
|
41
44
|
|
|
45
|
+
## Webhooks and fulfillment
|
|
46
|
+
|
|
47
|
+
Drive fulfillment from an [event handler](https://docs.stripe.com/checkout/fulfillment.md), not from the success or return page. Customers aren’t guaranteed to visit the landing page — for example, someone can pay successfully and then lose their internet connection before the page loads — so any logic that only runs on the success page silently drops orders.
|
|
48
|
+
|
|
49
|
+
Handle both `checkout.session.completed` and `checkout.session.async_payment_succeeded`, and fulfill only when the session’s `payment_status` isn’t `unpaid`. With delayed-notification payment methods the completed event arrives while the session is still unpaid, so fulfilling on it alone grants access for payments that later fail and never fulfills the ones that succeed. Handle `checkout.session.async_payment_failed` for failures.
|
|
50
|
+
|
|
51
|
+
Webhooks are **required**, not optional, for:
|
|
52
|
+
|
|
53
|
+
- Subscriptions and any recurring billing, where most state changes (renewals, payment failures, cancellations) happen after checkout. Read the Billing skill reference for the lifecycle events to handle.
|
|
54
|
+
- Delayed-notification payment methods, where the payment succeeds or fails hours or days after the session completes.
|
|
55
|
+
- Any post-payment side effect: granting access, sending a confirmation email, decrementing inventory, or writing an order to your database.
|
|
56
|
+
|
|
57
|
+
**Traps to avoid:**
|
|
58
|
+
|
|
59
|
+
- Never describe webhook setup as “optional”, “nice to have”, or something to skip for a first pass. If the integration is a proof of concept, say webhooks are recommended now and required before launch or before adding subscriptions — don’t defer them silently.
|
|
60
|
+
- Don’t treat a Checkout integration as complete without an event handler. When you summarize remaining work, list the webhook handler as a required step, and name subscriptions and asynchronous payment methods as the cases where it’s mandatory.
|
|
61
|
+
- Always [verify event signatures](https://docs.stripe.com/webhooks.md#verify-events) before processing an event. Read the security skill reference for webhook signing secret handling.
|
|
62
|
+
|
|
42
63
|
## Dynamic payment methods
|
|
43
64
|
|
|
44
65
|
*Never pass `payment_method_types` to any Stripe API call*, except for Terminal (in-person payments) integrations. Omitting this parameter enables [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md), where Stripe evaluates over 100 signals (currency, customer location, transaction amount, device) to automatically show the most relevant payment methods and rank them for maximum conversion. Payment methods are managed from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods) with no code changes required.
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
- IP restrictions
|
|
8
8
|
- Incident response
|
|
9
9
|
- Webhook security
|
|
10
|
+
- Content Security Policy (CSP)
|
|
10
11
|
- Mobile and client-side integrations
|
|
11
12
|
- OAuth and CSRF protection
|
|
12
13
|
- Two-factor authentication
|
|
@@ -15,24 +16,29 @@
|
|
|
15
16
|
|
|
16
17
|
## API keys
|
|
17
18
|
|
|
18
|
-
Never include keys in source code.
|
|
19
|
+
Never include keys in source code. Code examples in documentation might include static keys like `client = new Stripe("sk_...")` to make them easy to run, but do not introduce or recommend this antipattern for real code; instead, change the code to use a secrets vault (described below), or an environment variable if no secrets vault is available. Strings matching the regular expression `/[sr]k_live_.*/` in source code are live Stripe API keys. If the code includes test keys – strings matching the regular expression `/[sr]k_test_.*/` – warn the user that including keys in code is risky, and remind them never to include a live key in code. Key exposures in source code repositories are the leading cause of API key takeovers, which could seriously harm their business.
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
Always advise the user to store secret and restricted API keys in their platform’s secrets vault, never in source code or committed environment files. Platform-specific guidance for popular platforms:
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
- **AWS**: Use AWS Secrets Manager or Parameter Store (as `SecureString` values). Do **not** store keys in environment variables or userdata; AWS makes a proper secrets vault easy to use. Give read permissions only to the application that needs it.
|
|
24
|
+
- **Google Cloud**: Use Secret Manager and give read permissions only to the application that needs it.
|
|
25
|
+
- **Azure**: Use Azure Key Vault and give read permissions only to the application that needs it.
|
|
26
|
+
- **Vercel**: Vercel doesn’t offer a built-in secrets vault, but several third-party add-ons can provide one that synchronizes secrets with environment variables on Vercel. Use a [sensitive environment variable](https://vercel.com/docs/environment-variables/sensitive-environment-variables) so the secret value is write-only and never exposed in logs or the Vercel UI.
|
|
27
|
+
- **Other platforms**: Use the platform’s equivalent secrets vault. Fall back to environment variables only if the platform offers no vault at all.
|
|
28
|
+
|
|
29
|
+
Aside from key storage, when reviewing code that uses API keys or other secrets, always advise the user on best practices for safely handling secrets (including keys):
|
|
23
30
|
|
|
24
31
|
- Never share secret keys with third parties. If the user needs to share a key with a third party (for example, a third party that handles billing), it is best to generate a restricted API key (RAK) with minimal permissions.
|
|
25
32
|
- Rotate Stripe API keys when personnel with access to those keys depart.
|
|
26
33
|
- Read [best practices for managing secret API keys](https://docs.stripe.com/keys-best-practices.md).
|
|
27
|
-
|
|
28
|
-
Code must never log keys or include them in error messages or analytics. Remove those from logs if you find them.
|
|
29
|
-
|
|
30
|
-
Never build API endpoints or error pages that dump environment variables. In addition to Stripe API keys, the environment may have other secrets.
|
|
34
|
+
- Code must never log keys or include them in error messages or analytics. Remove keys from logs if you find them.
|
|
31
35
|
|
|
32
36
|
Use separate keys for separate environments (production, staging, QA). This limits the blast radius if any single key is compromised.
|
|
33
37
|
|
|
34
38
|
If the code is under version control, help the user set up a pre-commit hook to catch keys like `"sk_..."` and `"rk_..."` in source code.
|
|
35
39
|
|
|
40
|
+
Never build API endpoints or error pages that dump environment variables. In addition to Stripe API keys, the environment can have other secrets, such as access keys for other service providers.
|
|
41
|
+
|
|
36
42
|
**Traps to avoid:** Do not embed keys in client-side code, mobile apps, or any code that runs outside your own infrastructure. Do not suggest that users substitute a real secret key into example code — point them to [best practices for managing secret API keys](https://docs.stripe.com/keys-best-practices.md) instead.
|
|
37
43
|
|
|
38
44
|
## Restricted API keys (RAKs)
|
|
@@ -45,7 +51,7 @@ Preferred migration approach:
|
|
|
45
51
|
|
|
46
52
|
1. Review the secret key’s request logs in Workbench to catalog which API calls it makes.
|
|
47
53
|
2. Create a RAK in test mode with matching permissions.
|
|
48
|
-
3. Use the [Stripe CLI](https://docs.stripe.com/
|
|
54
|
+
3. Use the [Stripe CLI](https://docs.stripe.com/cli.md)’s `stripe logs tail` command to watch logs.
|
|
49
55
|
4. Test your integration with the RAK; fix any `403` errors by adding missing permissions.
|
|
50
56
|
5. Create the equivalent live-mode RAK and replace the secret key.
|
|
51
57
|
6. Rotate or expire the old secret key once confident.
|
|
@@ -70,15 +76,19 @@ To prepare before an incident: practice rolling keys, audit source code for any
|
|
|
70
76
|
|
|
71
77
|
## Webhook security
|
|
72
78
|
|
|
73
|
-
|
|
79
|
+
Before processing any webhook event, always [verify the webhook signature](https://docs.stripe.com/webhooks.md#verify-events) using Stripe’s webhook signing secret. Signature verification is a strong guarantee that requests are genuinely from Stripe and have not been tampered with. Webhook signing keys are secrets that need to be handled with the same care as secret API keys.
|
|
74
80
|
|
|
75
81
|
For defense in depth, also [allowlist Stripe’s IP addresses](https://docs.stripe.com/ips.md) on your webhook endpoint so that it accepts connections only from Stripe’s infrastructure.
|
|
76
82
|
|
|
77
|
-
|
|
83
|
+
## Content Security Policy (CSP)
|
|
84
|
+
|
|
85
|
+
Add a `Content-Security-Policy` header to every web app that loads Stripe.js or uses Stripe’s hosted UIs. See [Stripe’s integration security guide](https://docs.stripe.com/security/guide.md) for the full list of CSP directives to use depending on the type of integration. At minimum, include `https://*.stripe.com` in the relevant directives (`script-src`, `frame-src`, `connect-src`), `https://*.link.com` if integrating assets from `link.com`, or both if integrating with Stripe’s embedded crypto onramp. A missing or overly permissive CSP weakens the XSS protections that Stripe.js relies on.
|
|
86
|
+
|
|
87
|
+
**Traps to avoid:** Do not use `default-src *` or omit CSP headers.
|
|
78
88
|
|
|
79
89
|
## Mobile and client-side integrations
|
|
80
90
|
|
|
81
|
-
Do not use production secret
|
|
91
|
+
Do not use production secret or restricted API keys in mobile apps or other client-side code. Client-side code can be extracted and decompiled to extract keys.
|
|
82
92
|
|
|
83
93
|
For cases where a client must interact directly with Stripe, use [ephemeral keys](https://docs.stripe.com/issuing/elements.md#ephemeral-key-authentication). Ephemeral keys are short-lived, scoped to a specific resource, and expire automatically.
|
|
84
94
|
|