vybekiit 0.7.25 → 0.7.27

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.
Files changed (247) hide show
  1. package/dist/bin.js +3891 -1301
  2. package/dist/global-skills/aws-cdk/SKILL.md +19 -5
  3. package/dist/global-skills/aws-cdk/references/fast-deployments.md +191 -0
  4. package/dist/global-skills/aws-cdk/references/troubleshooting-deployment.md +16 -0
  5. package/dist/global-skills/aws-cloudformation/SKILL.md +16 -26
  6. package/dist/global-skills/aws-cloudformation/references/check-cloudformation-template-compliance.script.md +7 -3
  7. package/dist/global-skills/aws-cloudformation/references/cloudformation-language-server.md +177 -0
  8. package/dist/global-skills/aws-cloudformation/references/cloudformation-pre-deploy-validation.script.md +8 -2
  9. package/dist/global-skills/aws-cloudformation/references/persist-template-context.script.md +5 -8
  10. package/dist/global-skills/aws-cloudformation/references/retrieve-template-context.script.md +1 -1
  11. package/dist/global-skills/aws-cloudformation/references/security-considerations.md +51 -0
  12. package/dist/global-skills/aws-cloudformation/references/troubleshoot-failed-stack.script.md +138 -0
  13. package/dist/global-skills/aws-cloudformation/references/{validate-cloudformation-template.script.md → validate-with-cfn-lint.script.md} +15 -27
  14. package/dist/global-skills/aws-cloudformation/references/validate-with-cloudformation-validate.script.md +181 -0
  15. package/dist/global-skills/aws-cloudformation/references/validation-tool-selection.md +44 -0
  16. package/dist/global-skills/aws-serverless/SKILL.md +9 -1
  17. package/dist/global-skills/aws-serverless/references/architecture.md +3 -1
  18. package/dist/global-skills/aws-serverless/references/lambda.md +3 -1
  19. package/dist/global-skills/aws-serverless/references/orchestration.md +1 -0
  20. package/dist/global-skills/better-auth-best-practices/SKILL.md +18 -8
  21. package/dist/global-skills/eas-app-stores/SKILL.md +31 -15
  22. package/dist/global-skills/eas-app-stores/agents/openai.yaml +2 -2
  23. package/dist/global-skills/eas-app-stores/references/ios-app-store.md +37 -32
  24. package/dist/global-skills/eas-app-stores/references/native-ios.md +167 -0
  25. package/dist/global-skills/eas-app-stores/references/play-store.md +3 -7
  26. package/dist/global-skills/eas-app-stores/references/testflight.md +39 -35
  27. package/dist/global-skills/eas-simulator/SKILL.md +48 -26
  28. package/dist/global-skills/eas-simulator/references/controllers.md +32 -3
  29. package/dist/global-skills/eas-simulator/references/run-your-app.md +34 -4
  30. package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -4
  31. package/dist/global-skills/eas-update/SKILL.md +146 -0
  32. package/dist/global-skills/eas-update/agents/openai.yaml +4 -0
  33. package/dist/global-skills/expo-animation/RECIPES.md +2 -2
  34. package/dist/global-skills/expo-animation/SKILL.md +9 -2
  35. package/dist/global-skills/expo-brownfield/SKILL.md +18 -11
  36. package/dist/global-skills/expo-brownfield/agents/openai.yaml +2 -2
  37. package/dist/global-skills/expo-brownfield/references/brownfield-integrated.md +94 -69
  38. package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +40 -42
  39. package/dist/global-skills/expo-brownfield/references/comparison.md +5 -5
  40. package/dist/global-skills/expo-brownfield/references/feature-integration.md +163 -0
  41. package/dist/global-skills/expo-brownfield/references/troubleshooting.md +17 -17
  42. package/dist/global-skills/expo-brownfield/references/version-compatibility.md +40 -0
  43. package/dist/global-skills/expo-data-fetching/SKILL.md +27 -6
  44. package/dist/global-skills/expo-design-system/SKILL.md +27 -7
  45. package/dist/global-skills/expo-design-system/references/audit.md +7 -2
  46. package/dist/global-skills/expo-design-system/references/native-slop.md +74 -0
  47. package/dist/global-skills/expo-examples/SKILL.md +0 -1
  48. package/dist/global-skills/expo-examples/references/catalog.md +1 -1
  49. package/dist/global-skills/expo-migrate-module/SKILL.md +21 -10
  50. package/dist/global-skills/expo-migrate-module/references/compatibility.md +80 -23
  51. package/dist/global-skills/expo-migrate-module/references/migration-map.md +162 -11
  52. package/dist/global-skills/expo-native-ui/SKILL.md +25 -16
  53. package/dist/global-skills/expo-native-ui/agents/openai.yaml +2 -2
  54. package/dist/global-skills/expo-native-ui/references/controls.md +5 -46
  55. package/dist/global-skills/expo-native-ui/references/icons.md +21 -2
  56. package/dist/global-skills/expo-native-ui/references/media.md +15 -20
  57. package/dist/global-skills/expo-native-ui/references/visual-effects.md +12 -11
  58. package/dist/global-skills/expo-overview/SKILL.md +17 -12
  59. package/dist/global-skills/expo-router/SKILL.md +5 -3
  60. package/dist/global-skills/expo-router/references/tabs.md +5 -5
  61. package/dist/global-skills/expo-skill-eval/scripts/check-static.sh +0 -0
  62. package/dist/global-skills/expo-skill-eval/scripts/clean-fixture.sh +0 -0
  63. package/dist/global-skills/expo-skill-eval/scripts/latest-sdk.sh +0 -0
  64. package/dist/global-skills/expo-skill-eval/scripts/make-fixture.sh +0 -0
  65. package/dist/global-skills/expo-skill-eval/scripts/make-workspace.sh +0 -0
  66. package/dist/global-skills/expo-skill-eval/scripts/snapshot-android.sh +0 -0
  67. package/dist/global-skills/expo-skill-eval/scripts/snapshot-ios.sh +0 -0
  68. package/dist/global-skills/expo-skill-eval/scripts/snapshot-web.sh +0 -0
  69. package/dist/global-skills/expo-upgrade/SKILL.md +3 -1
  70. package/dist/global-skills/expo-web-to-native/references/false-friends.md +2 -2
  71. package/dist/global-skills/expo-web-to-native/references/native-patterns.md +1 -1
  72. package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +13 -16
  73. package/dist/global-skills/firebase-ai-logic-basics/references/ios_setup.md +4 -5
  74. package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_android.md +4 -4
  75. package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_web.md +3 -3
  76. package/dist/global-skills/firebase-auth-basics/SKILL.md +11 -6
  77. package/dist/global-skills/firebase-auth-basics/references/client_sdk_android.md +4 -5
  78. package/dist/global-skills/firebase-auth-basics/references/client_sdk_web.md +3 -3
  79. package/dist/global-skills/firebase-auth-basics/references/flutter_setup.md +24 -25
  80. package/dist/global-skills/firebase-auth-basics/references/security_rules.md +4 -2
  81. package/dist/global-skills/firebase-crashlytics/references/android_setup.md +7 -4
  82. package/dist/global-skills/firebase-crashlytics/references/ios_setup.md +2 -3
  83. package/dist/global-skills/firebase-data-connect/SKILL.md +2 -1
  84. package/dist/global-skills/firebase-data-connect/examples.md +4 -4
  85. package/dist/global-skills/firebase-data-connect/reference/config.md +5 -4
  86. package/dist/global-skills/firebase-data-connect/reference/realtime.md +1 -2
  87. package/dist/global-skills/firebase-data-connect/reference/sdk_flutter.md +2 -2
  88. package/dist/global-skills/firebase-data-connect/reference/sdk_ios.md +2 -2
  89. package/dist/global-skills/firebase-data-connect/reference/sdk_web.md +17 -6
  90. package/dist/global-skills/firebase-data-connect/reference/security.md +5 -5
  91. package/dist/global-skills/firebase-data-connect/templates.md +2 -1
  92. package/dist/global-skills/firebase-firestore/SKILL.md +20 -8
  93. package/dist/global-skills/firebase-firestore/references/enterprise/android_sdk_usage.md +5 -4
  94. package/dist/global-skills/firebase-firestore/references/enterprise/data_model.md +12 -3
  95. package/dist/global-skills/firebase-firestore/references/enterprise/indexes.md +16 -18
  96. package/dist/global-skills/firebase-firestore/references/enterprise/provisioning.md +1 -1
  97. package/dist/global-skills/firebase-firestore/references/enterprise/python_sdk_usage.md +5 -1
  98. package/dist/global-skills/firebase-firestore/references/enterprise/web_sdk_usage.md +7 -7
  99. package/dist/global-skills/firebase-firestore/references/standard/android_sdk_usage.md +5 -5
  100. package/dist/global-skills/firebase-firestore/references/standard/flutter_setup.md +4 -4
  101. package/dist/global-skills/firebase-firestore/references/standard/indexes.md +16 -18
  102. package/dist/global-skills/firebase-firestore/references/standard/provisioning.md +1 -1
  103. package/dist/global-skills/firebase-remote-config-basics/SKILL.md +0 -5
  104. package/dist/global-skills/firebase-remote-config-basics/references/android_setup.md +36 -8
  105. package/dist/global-skills/firebase-remote-config-basics/references/ios_setup.md +1 -7
  106. package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +17 -6
  107. package/dist/global-skills/{firebase-firestore/references/standard/security_rules.md → firestore-rules-creation/SKILL.md} +24 -13
  108. package/dist/global-skills/grow-my-customers/SKILL.md +23 -0
  109. package/dist/global-skills/instrument-feature-flags/SKILL.md +25 -25
  110. package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +141 -285
  111. package/dist/global-skills/instrument-feature-flags/references/android.md +6 -15
  112. package/dist/global-skills/instrument-feature-flags/references/api.md +4 -11
  113. package/dist/global-skills/instrument-feature-flags/references/best-practices.md +1 -13
  114. package/dist/global-skills/instrument-feature-flags/references/django.md +14 -27
  115. package/dist/global-skills/instrument-feature-flags/references/dotnet.md +20 -79
  116. package/dist/global-skills/instrument-feature-flags/references/elixir.md +1 -9
  117. package/dist/global-skills/instrument-feature-flags/references/flask.md +13 -13
  118. package/dist/global-skills/instrument-feature-flags/references/flutter.md +3 -24
  119. package/dist/global-skills/instrument-feature-flags/references/go.md +3 -15
  120. package/dist/global-skills/instrument-feature-flags/references/ios.md +4 -17
  121. package/dist/global-skills/instrument-feature-flags/references/java.md +5 -13
  122. package/dist/global-skills/instrument-feature-flags/references/laravel.md +13 -17
  123. package/dist/global-skills/instrument-feature-flags/references/next-js.md +25 -32
  124. package/dist/global-skills/instrument-feature-flags/references/nodejs.md +8 -15
  125. package/dist/global-skills/instrument-feature-flags/references/php.md +1 -15
  126. package/dist/global-skills/instrument-feature-flags/references/python.md +2 -15
  127. package/dist/global-skills/instrument-feature-flags/references/react-native.md +13 -15
  128. package/dist/global-skills/instrument-feature-flags/references/react.md +17 -21
  129. package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +37 -83
  130. package/dist/global-skills/instrument-feature-flags/references/ruby.md +2 -15
  131. package/dist/global-skills/instrument-feature-flags/references/rust.md +13 -25
  132. package/dist/global-skills/instrument-feature-flags/references/usage.md +14 -63
  133. package/dist/global-skills/instrument-feature-flags/references/web.md +9 -14
  134. package/dist/global-skills/instrument-product-analytics/SKILL.md +29 -29
  135. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +3 -1
  136. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +3 -1
  137. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-static.md +3 -1
  138. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-view-transitions.md +3 -1
  139. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +3 -1
  140. package/dist/global-skills/instrument-product-analytics/references/android.md +72 -107
  141. package/dist/global-skills/instrument-product-analytics/references/angular.md +26 -28
  142. package/dist/global-skills/instrument-product-analytics/references/astro.md +13 -24
  143. package/dist/global-skills/instrument-product-analytics/references/configuration.md +45 -63
  144. package/dist/global-skills/instrument-product-analytics/references/django.md +14 -27
  145. package/dist/global-skills/instrument-product-analytics/references/dotnet.md +20 -79
  146. package/dist/global-skills/instrument-product-analytics/references/elixir.md +47 -49
  147. package/dist/global-skills/instrument-product-analytics/references/flask.md +13 -13
  148. package/dist/global-skills/instrument-product-analytics/references/flutter.md +60 -90
  149. package/dist/global-skills/instrument-product-analytics/references/go.md +17 -56
  150. package/dist/global-skills/instrument-product-analytics/references/identify-users.md +15 -15
  151. package/dist/global-skills/instrument-product-analytics/references/ios.md +11 -15
  152. package/dist/global-skills/instrument-product-analytics/references/laravel.md +13 -17
  153. package/dist/global-skills/instrument-product-analytics/references/next-js.md +25 -32
  154. package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +13 -27
  155. package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +14 -28
  156. package/dist/global-skills/instrument-product-analytics/references/php.md +33 -84
  157. package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +229 -9
  158. package/dist/global-skills/instrument-product-analytics/references/python.md +415 -106
  159. package/dist/global-skills/instrument-product-analytics/references/react-native.md +161 -155
  160. package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +12 -33
  161. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +15 -33
  162. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +12 -33
  163. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +26 -41
  164. package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +37 -83
  165. package/dist/global-skills/instrument-product-analytics/references/ruby.md +48 -108
  166. package/dist/global-skills/instrument-product-analytics/references/svelte.md +18 -24
  167. package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +17 -19
  168. package/dist/global-skills/instrument-product-analytics/references/usage.md +14 -63
  169. package/dist/global-skills/instrument-product-analytics/references/vue-js.md +29 -28
  170. package/dist/global-skills/manifest.json +8 -2
  171. package/dist/global-skills/mongodb-search-and-ai/SKILL.md +28 -37
  172. package/dist/global-skills/mongodb-search-and-ai/references/automated-embedding.md +438 -0
  173. package/dist/global-skills/mongodb-search-and-ai/references/hybrid-search.md +60 -4
  174. package/dist/global-skills/mongodb-search-and-ai/references/vector-search.md +46 -108
  175. package/dist/global-skills/neon/SKILL.md +207 -213
  176. package/dist/global-skills/neon/references/auth.md +12 -0
  177. package/dist/global-skills/neon/references/claimable-neon.md +10 -14
  178. package/dist/global-skills/neon/references/function-triggers.md +53 -0
  179. package/dist/global-skills/neon/references/logs-loki.md +61 -0
  180. package/dist/global-skills/neon/references/parse-env.md +32 -0
  181. package/dist/global-skills/neon/references/sdk.md +7 -0
  182. package/dist/global-skills/neon-ai-gateway/SKILL.md +14 -16
  183. package/dist/global-skills/neon-auth/SKILL.md +155 -0
  184. package/dist/global-skills/neon-auth/references/managed-auth.md +173 -0
  185. package/dist/global-skills/neon-auth/references/self-managed.md +25 -0
  186. package/dist/global-skills/neon-functions/SKILL.md +159 -84
  187. package/dist/global-skills/neon-functions/references/ai-sdk.md +4 -6
  188. package/dist/global-skills/neon-functions/references/function-triggers.md +249 -0
  189. package/dist/global-skills/neon-functions/references/mastra-studio.md +3 -3
  190. package/dist/global-skills/neon-functions/references/mcp.md +1 -1
  191. package/dist/global-skills/neon-functions/references/production-hardening.md +340 -0
  192. package/dist/global-skills/neon-functions/references/sse.md +8 -5
  193. package/dist/global-skills/neon-object-storage/SKILL.md +10 -11
  194. package/dist/global-skills/neon-postgres/SKILL.md +120 -17
  195. package/dist/global-skills/neon-postgres/references/full-text-search.md +99 -0
  196. package/dist/global-skills/neon-postgres/references/hybrid-search.md +90 -0
  197. package/dist/global-skills/neon-postgres/references/lakebase-search-drizzle.md +172 -0
  198. package/dist/global-skills/neon-postgres/references/vector-search.md +137 -0
  199. package/dist/global-skills/neon-postgres-branches/SKILL.md +3 -3
  200. package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +1 -1
  201. package/dist/global-skills/onboarding/SKILL.md +8 -6
  202. package/dist/global-skills/resend/SKILL.md +4 -2
  203. package/dist/global-skills/resend/references/broadcasts.md +6 -1
  204. package/dist/global-skills/resend/references/receiving.md +29 -10
  205. package/dist/global-skills/resend/references/sending/email-management.md +14 -4
  206. package/dist/global-skills/resend/references/topics.md +9 -6
  207. package/dist/global-skills/resend/references/usage.md +117 -0
  208. package/dist/global-skills/resend/references/webhooks.md +59 -2
  209. package/dist/global-skills/stripe-best-practices/SKILL.md +35 -29
  210. package/dist/global-skills/stripe-best-practices/references/billing.md +9 -2
  211. package/dist/global-skills/stripe-best-practices/references/payments.md +4 -2
  212. package/dist/global-skills/stripe-best-practices/references/security.md +3 -1
  213. package/dist/global-skills/stripe-best-practices/references/tax.md +39 -20
  214. package/dist/global-skills/supabase/SKILL.md +6 -0
  215. package/dist/global-skills/use-railway/SKILL.md +42 -22
  216. package/dist/global-skills/use-railway/references/analyze-db.md +7 -6
  217. package/dist/global-skills/use-railway/references/cloud-agents.md +70 -0
  218. package/dist/global-skills/use-railway/references/configure.md +17 -2
  219. package/dist/global-skills/use-railway/references/databases.md +107 -0
  220. package/dist/global-skills/use-railway/references/deploy.md +5 -5
  221. package/dist/global-skills/use-railway/references/feature-flags.md +25 -13
  222. package/dist/global-skills/use-railway/references/iac.md +66 -77
  223. package/dist/global-skills/use-railway/references/operate.md +26 -3
  224. package/dist/global-skills/use-railway/references/request.md +31 -23
  225. package/dist/global-skills/use-railway/references/setup.md +16 -5
  226. package/dist/global-skills/use-railway/references/tracing.md +261 -0
  227. package/dist/global-skills/use-railway/references/usage.md +52 -0
  228. package/dist/global-skills/use-railway/scripts/analyze-mongo.py +0 -0
  229. package/dist/global-skills/use-railway/scripts/analyze-mysql.py +0 -0
  230. package/dist/global-skills/use-railway/scripts/analyze-postgres.py +0 -0
  231. package/dist/global-skills/use-railway/scripts/analyze-redis.py +0 -0
  232. package/dist/global-skills/use-railway/scripts/enable-pg-stats.py +0 -0
  233. package/dist/global-skills/use-railway/scripts/pg-extensions.py +0 -0
  234. package/dist/global-skills/use-railway/scripts/railway-api.sh +0 -0
  235. package/dist/global-skills/validate-my-idea/SKILL.md +54 -0
  236. package/dist/global-skills/{feedback → vybekiit-feedback}/SKILL.md +16 -12
  237. package/dist/global-skills/watch-my-app/SKILL.md +53 -0
  238. package/dist/global-skills/workers-best-practices/SKILL.md +36 -103
  239. package/dist/global-skills/workers-best-practices/references/configuration.md +139 -0
  240. package/dist/global-skills/workers-best-practices/references/platform-apis.md +51 -0
  241. package/dist/global-skills/workers-best-practices/references/{rules.md → runtime-patterns.md} +13 -137
  242. package/dist/global-skills/wrangler/SKILL.md +48 -901
  243. package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Sources/main.swift +19 -15
  244. package/package.json +22 -22
  245. package/dist/global-skills/expo-native-ui/references/animations.md +0 -220
  246. package/dist/global-skills/firebase-firestore/references/enterprise/security_rules.md +0 -577
  247. package/dist/global-skills/workers-best-practices/references/review.md +0 -174
@@ -0,0 +1,137 @@
1
+ # Semantic Vector Search
2
+
3
+ Use `lakebase_vector` for approximate nearest-neighbor retrieval over embeddings. It retains pgvector's vector types, distance operators, and query syntax; the index access method is `lakebase_ann`.
4
+
5
+ ## Contents
6
+
7
+ - [Create the extension](#create-the-extension) — enable `lakebase_vector` and its `pgvector` dependency
8
+ - [Prepare embeddings](#prepare-embeddings) — define the vector column and keep embedding dimensions consistent
9
+ - [Build the index](#build-the-index) — match the distance metric, operator class, and query operator
10
+ - [Tune the index](#tune-the-index) — configure index-build options and concurrent index management
11
+ - [Query](#query) — rank by vector distance or filter by a similarity radius
12
+ - [Tune search](#tune-search) — inspect the index and tune recall against latency
13
+ - [Use prefilter selectively](#use-prefilter-selectively) — apply selective filters before ANN scoring
14
+
15
+ ## Create the Extension
16
+
17
+ Lakebase Search requires Postgres 16 or later. Enable the extension before creating vector columns or indexes:
18
+
19
+ ```sql
20
+ CREATE EXTENSION IF NOT EXISTS lakebase_vector CASCADE;
21
+ ```
22
+
23
+ `lakebase_vector` installs `pgvector` through `CASCADE`. It relies on a preloaded library that Neon enables by default; if the project customized its preloaded-library list, confirm the library remains enabled.
24
+
25
+ ## Prepare Embeddings
26
+
27
+ Use any embedding provider whose vector dimensions and distance metric match the schema and index:
28
+
29
+ ```sql
30
+ CREATE TABLE documents (
31
+ id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
32
+ title text NOT NULL,
33
+ body text NOT NULL,
34
+ embedding vector(1536)
35
+ );
36
+ ```
37
+
38
+ Replace `1536` with the embedding model's dimension. Generate stored-document and query embeddings with the same model and preprocessing. Keep embedding generation outside SQL unless the architecture already provides an in-database embedding function.
39
+
40
+ ## Build the Index
41
+
42
+ Choose the operator class and query operator as a matched pair:
43
+
44
+ | Metric | Common use | Operator class | Distance operator |
45
+ | --- | --- | --- | --- |
46
+ | Cosine | Most text embeddings | `vector_cosine_ops` | `<=>` |
47
+ | L2 / Euclidean | Absolute distance matters; vectors do not need normalization | `vector_l2_ops` | `<->` |
48
+ | Inner product | Unit-normalized vectors; matches cosine for unit vectors | `vector_ip_ops` | `<#>` |
49
+
50
+ ```sql
51
+ CREATE INDEX documents_embedding_ann ON documents
52
+ USING lakebase_ann (embedding vector_cosine_ops);
53
+ ```
54
+
55
+ ## Tune the Index
56
+
57
+ The default index options suit most workloads:
58
+
59
+ - `build_mode = 'standard'` balances recall and index build time. Use `quality` for better recall when a longer build is acceptable.
60
+ - `lists = 'auto'` chooses the IVF partition layout from the number of indexed vectors. Choose between `auto` and a manual value case by case: test both on the target dataset and use the value that better meets recall and performance targets.
61
+
62
+ To prioritize recall over index build time:
63
+
64
+ ```sql
65
+ CREATE INDEX documents_embedding_ann_quality ON documents
66
+ USING lakebase_ann (embedding vector_cosine_ops)
67
+ WITH (build_mode = 'quality');
68
+ ```
69
+
70
+ To override the automatic partition layout instead:
71
+
72
+ ```sql
73
+ CREATE INDEX documents_embedding_ann_lists ON documents
74
+ USING lakebase_ann (embedding vector_cosine_ops)
75
+ WITH (lists = '1024');
76
+ ```
77
+
78
+ For a large table, use `CREATE INDEX CONCURRENTLY` to avoid locking out writes while creating the index. For a frequently changing table, periodically use `REINDEX INDEX CONCURRENTLY` to rebuild the index with minimal write locking.
79
+
80
+ ## Query
81
+
82
+ Generate the query embedding with the same model and preprocessing used for stored documents, then bind it as a parameter:
83
+
84
+ ```sql
85
+ SELECT id, title, embedding <=> $1::vector AS distance
86
+ FROM documents
87
+ ORDER BY distance
88
+ LIMIT $2;
89
+ ```
90
+
91
+ Distance sorts ascending: a smaller value is a closer match. Keep the query operator consistent with the index operator class.
92
+
93
+ To filter by a similarity radius, use the matching boolean range operator in `WHERE` and the distance operator in `ORDER BY`:
94
+
95
+ ```sql
96
+ SELECT id, title
97
+ FROM documents
98
+ WHERE embedding <<=>> sphere($1::vector, 0.5)
99
+ ORDER BY embedding <=> $1::vector
100
+ LIMIT $2;
101
+ ```
102
+
103
+ The cosine range operator `<<=>>` returns a boolean; do not use it as the ranking expression.
104
+
105
+ ## Tune Search
106
+
107
+ Inspect the index before overriding defaults:
108
+
109
+ ```sql
110
+ SELECT lakebase_ann_index_info('documents_embedding_ann');
111
+ ```
112
+
113
+ This reports `lists`, `default_probes`, and `default_epsilon`. Small datasets use exact flat search before IVF lists are built. In that state, `lists` and `default_probes` are empty. Leave `lakebase_ann.probes` set to its default of `'auto'`; `lakebase_ann.epsilon` still controls full-precision reranking during flat search.
114
+
115
+ For an IVF index, `lakebase_ann.probes` controls how many partitions are searched at each level. Higher values generally improve recall at the cost of speed. Its default is `'auto'`. When `lists` is not empty, the shape of `probes` must match the shape of `lists`: use one value for a one-level index or two comma-separated values for a two-level index. At each level, the `probes` value must be no larger than the corresponding `lists` value. A mismatched or out-of-range value causes an error.
116
+
117
+ `lakebase_ann.epsilon` controls how many candidates are reranked using full-precision distances. Higher values rerank more candidates and take longer. Its default is `'auto'`, which works well for most workloads.
118
+
119
+ ### Use Prefilter Selectively
120
+
121
+ By default, PostgreSQL applies non-vector filters after the ANN index returns candidate rows. Enable prefilter when a filter is cheap to evaluate and removes most rows. Leave it off for loose or expensive filters.
122
+
123
+ ```sql
124
+ BEGIN;
125
+ SET LOCAL lakebase_ann.prefilter = on;
126
+
127
+ SELECT id, title
128
+ FROM documents
129
+ WHERE id % 100 = 0
130
+ ORDER BY embedding <=> $1::vector
131
+ LIMIT $2;
132
+ COMMIT;
133
+ ```
134
+
135
+ Start with `probes` and `epsilon` set to `'auto'`. Benchmark manual probe values against representative query embeddings and choose the smallest values that satisfy recall and tail-latency targets. Keep session settings and the query in the same transaction when using a connection pool or stateless driver.
136
+
137
+ Source: [`lakebase_vector` documentation](https://neon.com/docs/extensions/lakebase-vector).
@@ -19,7 +19,7 @@ metadata:
19
19
  If the `neon` skill is not installed, fetch it from https://neon.com/docs/ai/skills/neon/SKILL.md or install it with:
20
20
 
21
21
  ```bash
22
- npx skills add neondatabase/agent-skills --skill neon
22
+ neon skills -s neon -y
23
23
  ```
24
24
 
25
25
  # Lakebase Postgres Branching
@@ -127,7 +127,7 @@ Schema-only branching is in Beta. If users report unexpected behavior, errors, o
127
127
  1. Ask them to share feedback in the Neon Console:
128
128
  - https://console.neon.tech/app/projects?modal=feedback
129
129
  2. Recommend opening a support conversation in the Neon Discord:
130
- - https://discord.gg/92vNTzKDGp
130
+ - https://neon.com/discord
131
131
 
132
132
  ## Reset from Parent
133
133
 
@@ -282,7 +282,7 @@ Common CI/CD use cases for Neon branches:
282
282
  - `neon branches create --name compliance-dev --parent main --schema-only --project-id <your-project-id> --expires-at 2026-12-15T18:02:16Z`
283
283
  5. Mention Beta support path:
284
284
  - https://console.neon.tech/app/projects?modal=feedback
285
- - https://discord.gg/92vNTzKDGp
285
+ - https://neon.com/discord
286
286
 
287
287
  ## Further Reading
288
288
 
@@ -19,7 +19,7 @@ metadata:
19
19
  If the `neon` skill is not installed, fetch it from https://neon.com/docs/ai/skills/neon/SKILL.md or install it with:
20
20
 
21
21
  ```bash
22
- npx skills add neondatabase/agent-skills --skill neon
22
+ neon skills -s neon -y
23
23
  ```
24
24
 
25
25
  # Postgres Egress Optimizer
@@ -27,8 +27,9 @@ translate every error · celebrate. Decide all technical choices yourself.
27
27
  **Verify:** if installed, `/onboarding` builds with practice UI.
28
28
 
29
29
  1. **Welcome + ask the one thing that matters.**
30
- Greet warmly. Ask: *"In one sentence, what do you want to build?"* Use their answer to tailor the
31
- starter page later — don't turn it into a technical interview.
30
+ Greet warmly. If the builder already described their app, use that description. Otherwise ask:
31
+ *"In one sentence, what do you want to build?"* Use their answer to tailor the starter page later.
32
+ Keep the conversation about their idea.
32
33
 
33
34
  1b. **One-time planning offer** (skip if `.vybekiit/state/planning-intro-seen` exists).
34
35
  Ask: *"Before we start building — want to **think it through together** first? I'll ask one question
@@ -42,9 +43,10 @@ translate every error · celebrate. Decide all technical choices yourself.
42
43
  First run `vybekiit doctor` — it installs the tools the app will need (for the database and for
43
44
  putting the app online) so the builder never configures anything. It may say a tool "isn't signed
44
45
  in yet" — that's fine for now; sign-in happens later, only when a step needs it (one browser click
45
- each). Then install the project's building blocks. Before starting the app, check whether
46
- `http://localhost:3000` already responds and reuse that running preview when it does. Otherwise,
47
- start exactly one preview with the agent's background-task support and keep its task handle.
46
+ each). Then install the project's building blocks. Check the URL printed by setup and the
47
+ project's running processes. Reuse a preview only after confirming it serves this app.
48
+ If none is running, choose an available port, start exactly one preview with the agent's
49
+ background-task support, and keep its task handle and URL.
48
50
  If a running preview is unhealthy, inspect and restart that same process instead of starting a
49
51
  second copy. Do this yourself, in plain words.
50
52
  After dependencies install, run **quality smoke** yourself: `pnpm verify` (format, lint, typecheck,
@@ -61,7 +63,7 @@ translate every error · celebrate. Decide all technical choices yourself.
61
63
  > `setup-payments` runs — same merge guide.
62
64
 
63
65
  3. **Show them their app.**
64
- Give them the one link to open (`http://localhost:3000`) and tell them what they'll see.
66
+ Give them the verified preview link from this run and tell them what they'll see.
65
67
  **Verify:** ask them to confirm they can see the page. Don't continue until they say yes.
66
68
  🎉 *Celebrate* — their app is alive.
67
69
  Mention Report mode once: *"If something looks wrong, press Option+Shift+R (Alt+Shift+R on
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: resend
3
- description: Use when working with the Resend email API — sending transactional emails (single or batch), receiving inbound emails via webhooks, managing email templates, tracking delivery events, managing domains, contacts, broadcasts, webhooks, API keys, automations, events, viewing API request logs, or setting up the Resend SDK. Always use this skill when the user mentions Resend, even for simple tasks like "send an email with Resend" — the skill contains critical gotchas (idempotency keys, webhook verification, template variable syntax) that prevent common production issues.
3
+ description: Use when working with the Resend email API — sending transactional emails (single or batch), receiving inbound emails via webhooks, managing email templates, tracking delivery events, managing domains, contacts, broadcasts, webhooks, API keys, automations, events, viewing API request logs, checking account usage and quotas, or setting up the Resend SDK. Always use this skill when the user mentions Resend, even for simple tasks like "send an email with Resend" — the skill contains critical gotchas (idempotency keys, webhook verification, template variable syntax) that prevent common production issues.
4
4
  license: MIT
5
5
  metadata:
6
6
  author: resend
7
- version: "3.6.0"
7
+ version: "3.12.0"
8
8
  homepage: https://resend.com/agent-skills
9
9
  source: https://github.com/resend/resend-skills
10
10
  openclaw:
@@ -44,6 +44,7 @@ references:
44
44
  - topics.md
45
45
  - automations.md
46
46
  - events.md
47
+ - usage.md
47
48
  - installation.md
48
49
  - fetch-all-templates.mjs
49
50
  ---
@@ -170,6 +171,7 @@ export async function POST(req: Request) {
170
171
  | **Manage topics** (subscriptions) | [topics.md](references/topics.md) — opt-in/out preferences, broadcast filtering |
171
172
  | **Create automations** (event-driven workflows) | [automations.md](references/automations.md) — steps, connections, runs, conditions |
172
173
  | **Define and send events** (automation triggers) | [events.md](references/events.md) — schemas, payloads, contact association |
174
+ | **Check account usage and quotas** | [usage.md](references/usage.md) — emails, contacts, segments, broadcasts, AI credits, automation runs, domains, rate limit |
173
175
  | **Install SDK** (8+ languages) | [installation.md](references/installation.md) |
174
176
  | **Set up an AI agent inbox** | Install the `agent-email-inbox` skill — covers security levels for untrusted input |
175
177
 
@@ -11,6 +11,7 @@ Send emails to audience segments. Broadcasts follow a two-step lifecycle: **crea
11
11
  | List | `resend.broadcasts.list(params)` | `resend.Broadcasts.list(params)` |
12
12
  | Send | `resend.broadcasts.send(id, params?)` | `resend.Broadcasts.send(params)` |
13
13
  | Cancel | `resend.broadcasts.cancel(id)` | `resend.Broadcasts.cancel(id)` |
14
+ | Duplicate | `resend.broadcasts.duplicate(id)` | `resend.Broadcasts.duplicate(id)` |
14
15
  | Update | `resend.broadcasts.update(id, params)` | `resend.Broadcasts.update(params)` |
15
16
  | Delete | `resend.broadcasts.remove(id)` | `resend.Broadcasts.remove(id)` |
16
17
  | Clicked Links | `resend.broadcasts.clickedLinks(id, params?)` | `resend.Broadcasts.clicked_links(id, params?)` |
@@ -69,7 +70,7 @@ const { data, error } = await resend.broadcasts.create({
69
70
  });
70
71
  ```
71
72
 
72
- ## Get, List, Update, Cancel, Delete
73
+ ## Get, List, Update, Cancel, Duplicate, Delete
73
74
 
74
75
  ```typescript
75
76
  // Get
@@ -87,6 +88,10 @@ const { data, error } = await resend.broadcasts.update('bc_abc123', {
87
88
  // reverts a scheduled one to draft. Does not remove the broadcast.
88
89
  const { data, error } = await resend.broadcasts.cancel('bc_abc123');
89
90
 
91
+ // Duplicate — creates a new draft named "<name> (copy)" with the same content.
92
+ // Works on any broadcast, including sent ones. Returns the new broadcast's id.
93
+ const { data, error } = await resend.broadcasts.duplicate('bc_abc123');
94
+
90
95
  // Delete — draft or scheduled only (deleting a scheduled broadcast also
91
96
  // cancels its delivery). Sent broadcasts cannot be deleted.
92
97
  const { data, error } = await resend.broadcasts.remove('bc_abc123');
@@ -167,7 +167,7 @@ const { data: attachments } = await resend.emails.receiving.attachments.list({
167
167
  emailId: event.data.email_id,
168
168
  });
169
169
 
170
- for (const attachment of attachments) {
170
+ for (const attachment of attachments.data) {
171
171
  console.log(attachment.filename);
172
172
  console.log(attachment.download_url); // signed URL, see expires_at
173
173
  console.log(attachment.expires_at);
@@ -179,7 +179,7 @@ for (const attachment of attachments) {
179
179
  ```typescript
180
180
  const { data: attachment } = await resend.emails.receiving.attachments.get({
181
181
  emailId: event.data.email_id,
182
- attachmentId: 'att_abc123',
182
+ id: 'att_abc123',
183
183
  });
184
184
 
185
185
  console.log(attachment.download_url); // signed URL
@@ -213,19 +213,33 @@ export async function POST(req: Request) {
213
213
 
214
214
  if (event.type === 'email.received') {
215
215
  // 1. Get email content
216
- const { data: email } = await resend.emails.receiving.get(
216
+ const { data: email, error: emailError } = await resend.emails.receiving.get(
217
217
  event.data.email_id
218
218
  );
219
219
 
220
+ if (emailError) {
221
+ console.error(emailError);
222
+ return new Response('Failed to fetch email', { status: 500 });
223
+ }
224
+
220
225
  // 2. Get attachments (if any)
221
- const { data: attachmentList } = await resend.emails.receiving.attachments.list({
222
- emailId: event.data.email_id,
223
- });
226
+ const { data: attachmentList, error: attachmentsError } =
227
+ await resend.emails.receiving.attachments.list({
228
+ emailId: event.data.email_id,
229
+ });
230
+
231
+ if (attachmentsError) {
232
+ console.error(attachmentsError);
233
+ return new Response('Failed to list attachments', { status: 500 });
234
+ }
224
235
 
225
236
  // 3. Download and encode attachments
226
237
  const attachments = await Promise.all(
227
- attachmentList.map(async (att) => {
238
+ attachmentList.data.map(async (att) => {
228
239
  const res = await fetch(att.download_url);
240
+ if (!res.ok) {
241
+ throw new Error(`Failed to download ${att.filename}`);
242
+ }
229
243
  const buffer = Buffer.from(await res.arrayBuffer());
230
244
  return {
231
245
  filename: att.filename,
@@ -235,14 +249,19 @@ export async function POST(req: Request) {
235
249
  );
236
250
 
237
251
  // 4. Forward the email (single send — batch doesn't support attachments)
238
- await resend.emails.send({
252
+ const { error: sendError } = await resend.emails.send({
239
253
  from: 'Support System <system@acme.com>',
240
254
  to: ['team@acme.com'],
241
255
  subject: `Fwd: ${email.subject}`,
242
- html: email.html,
243
- text: email.text,
256
+ html: email.html ?? undefined,
257
+ text: email.text ?? '',
244
258
  attachments,
245
259
  });
260
+
261
+ if (sendError) {
262
+ console.error(sendError);
263
+ return new Response('Failed to forward email', { status: 500 });
264
+ }
246
265
  }
247
266
 
248
267
  return new Response('OK', { status: 200 });
@@ -103,16 +103,21 @@ List and download attachments for sent emails. Returns metadata and a signed dow
103
103
  | Operation | Node.js | Python |
104
104
  |-----------|---------|--------|
105
105
  | List | `resend.emails.attachments.list({ emailId })` | `resend.Emails.Attachments.list(email_id)` |
106
- | Get | `resend.emails.attachments.get({ emailId, attachmentId })` | `resend.Emails.Attachments.get(email_id, attachment_id)` |
106
+ | Get | `resend.emails.attachments.get({ emailId, id })` | `resend.Emails.Attachments.get(email_id, attachment_id)` |
107
107
 
108
108
  ### Examples
109
109
 
110
110
  ```typescript
111
111
  // List all attachments for a sent email
112
- const { data: attachments } = await resend.emails.attachments.list({
112
+ const { data: attachments, error } = await resend.emails.attachments.list({
113
113
  emailId: 'email_abc123',
114
114
  });
115
115
 
116
+ if (error) {
117
+ console.error(error);
118
+ return;
119
+ }
120
+
116
121
  for (const att of attachments.data) {
117
122
  console.log(att.filename); // 'invoice.pdf'
118
123
  console.log(att.content_type); // 'application/pdf'
@@ -121,11 +126,16 @@ for (const att of attachments.data) {
121
126
  }
122
127
 
123
128
  // Get a single attachment
124
- const { data: attachment } = await resend.emails.attachments.get({
129
+ const { data: attachment, error: getError } = await resend.emails.attachments.get({
125
130
  emailId: 'email_abc123',
126
- attachmentId: 'att_def456',
131
+ id: 'att_def456',
127
132
  });
128
133
 
134
+ if (getError) {
135
+ console.error(getError);
136
+ return;
137
+ }
138
+
129
139
  // Download the content
130
140
  const response = await fetch(attachment.download_url);
131
141
  const buffer = await response.arrayBuffer();
@@ -20,8 +20,8 @@ Fine-grained subscription preferences — contacts opt in or out per topic. Topi
20
20
  |-----------|--------|
21
21
  | Create | `resend.Topics.create(params)` |
22
22
  | Get | `resend.Topics.get(id)` |
23
- | List | `resend.Topics.list()` |
24
- | Update | `resend.Topics.update(params)` |
23
+ | List | `resend.Topics.list(params?)` — `limit`, `after`, `before` |
24
+ | Update | `resend.Topics.update(id, params)` |
25
25
  | Delete | `resend.Topics.remove(id)` |
26
26
 
27
27
  ## Create Topic
@@ -31,7 +31,6 @@ const { data, error } = await resend.topics.create({
31
31
  name: 'Product Updates',
32
32
  defaultSubscription: 'opt_in', // REQUIRED: "opt_in" or "opt_out"
33
33
  description: 'New features and releases',
34
- visibility: 'public', // "public" or "private" (default: "private")
35
34
  });
36
35
 
37
36
  if (error) {
@@ -50,8 +49,13 @@ console.log(data.id); // topic_xxxxxxxx
50
49
  const { data, error } = await resend.topics.update({
51
50
  id: 'topic_xxx',
52
51
  name: 'Product News',
53
- visibility: 'public',
52
+ description: 'News about our products',
54
53
  });
54
+
55
+ if (error) {
56
+ console.error(error);
57
+ return;
58
+ }
55
59
  ```
56
60
 
57
61
  ## Managing Contact Subscriptions
@@ -90,7 +94,7 @@ await resend.broadcasts.create({
90
94
  | Name max length | 50 characters |
91
95
  | Description max length | 200 characters |
92
96
  | `defaultSubscription` | `"opt_in"` or `"opt_out"` — immutable after create |
93
- | `visibility` | `"public"` (shown on preference page) or `"private"` (default) |
97
+ | `visibility` | `"public"` (shown on the unsubscribe page) or `"private"` (default) |
94
98
 
95
99
  ## Common Mistakes
96
100
 
@@ -100,5 +104,4 @@ await resend.broadcasts.create({
100
104
  | Trying to change `defaultSubscription` | Immutable after creation — delete and recreate with new value |
101
105
  | Calling `.delete()` | SDK method is `.remove()` |
102
106
  | `visibility: "hidden"` | Not a valid value — use `"private"` |
103
- | Expecting `list()` to accept pagination | `topics.list()` takes no params — returns all topics |
104
107
  | Broadcast without `topicId` | Goes to all contacts in segment regardless of topic preferences |
@@ -0,0 +1,117 @@
1
+ # Usage
2
+
3
+ Account-level usage and quotas. A single snapshot endpoint — no ID, no pagination, no filters. Use it to check how close an account is to its plan limits for emails, contacts, segments, broadcasts, AI credits, automation runs, and domains, plus the account's API rate limit.
4
+
5
+ ## SDK Methods
6
+
7
+ | Operation | Node.js | Python |
8
+ |-----------|---------|--------|
9
+ | Get | `resend.usage.get()` | `resend.Usage.get()` |
10
+
11
+ Method naming per SDK: Ruby `Resend::Usage.get`, Go `client.Usage.Get()`, PHP `$resend->usage->get()`, Java `resend.usage().get()`, .NET `resend.UsageAsync()`, Rust `resend.usage.get().await`.
12
+
13
+ ## Get Usage
14
+
15
+ `GET /usage`
16
+
17
+ Takes no parameters.
18
+
19
+ ### Node.js
20
+
21
+ ```typescript
22
+ import { Resend } from 'resend';
23
+ const resend = new Resend(process.env.RESEND_API_KEY);
24
+
25
+ const { data, error } = await resend.usage.get();
26
+
27
+ if (error) {
28
+ console.error(error);
29
+ return;
30
+ }
31
+
32
+ console.log(`${data.emails.daily.used} emails today`);
33
+ console.log(`${data.contacts.used} / ${data.contacts.limit} contacts`);
34
+ ```
35
+
36
+ ### Python
37
+
38
+ ```python
39
+ import resend
40
+ import os
41
+
42
+ resend.api_key = os.environ["RESEND_API_KEY"]
43
+
44
+ usage = resend.Usage.get()
45
+
46
+ print(f'{usage["emails"]["daily"]["used"]} emails today')
47
+ print(f'{usage["contacts"]["used"]} / {usage["contacts"]["limit"]} contacts')
48
+ ```
49
+
50
+ ### cURL
51
+
52
+ ```bash
53
+ curl -s "https://api.resend.com/usage" \
54
+ -H "Authorization: Bearer $RESEND_API_KEY" \
55
+ -H "User-Agent: curl"
56
+ ```
57
+
58
+ ### Response
59
+
60
+ ```json
61
+ {
62
+ "object": "usage",
63
+ "emails": {
64
+ "daily": { "used": 258, "limit": null, "sent": 57, "received": 201, "resets_at": "2026-07-17T00:00:00.000Z" },
65
+ "monthly": { "used": 5442, "limit": 10000, "sent": 1000, "received": 4442, "resets_at": "2026-08-01T00:00:00.000Z" }
66
+ },
67
+ "contacts": { "used": 85000, "limit": 150000 },
68
+ "segments": { "used": 2, "limit": 3 },
69
+ "broadcasts": { "used": 100, "limit": null },
70
+ "ai_credits": { "used": 0, "limit": 500, "next_increase_at": "2026-07-18T09:00:00.000Z" },
71
+ "automation_runs": { "used": 0, "limit": 1000, "resets_at": "2026-08-01T00:00:00.000Z" },
72
+ "domains": { "used": 1, "limit": 1000 },
73
+ "rate_limit": { "limit": 10, "duration": "1000ms" }
74
+ }
75
+ ```
76
+
77
+ ## Response Fields
78
+
79
+ | Field | Type | Nullable | Description |
80
+ |-------|------|----------|--------------|
81
+ | `object` | string | No | Always `"usage"` |
82
+ | `emails.daily.used` | number | No | Emails sent + received in the current day (`sent` + `received`) |
83
+ | `emails.daily.limit` | number \| null | Yes | Plan's daily email cap. `null` when the plan has no daily cap (only a monthly one) |
84
+ | `emails.daily.sent` | number | No | Emails sent today |
85
+ | `emails.daily.received` | number | No | Emails received (inbound) today |
86
+ | `emails.daily.resets_at` | timestamp | No | When the daily counters next reset |
87
+ | `emails.monthly.used` | number | No | Emails sent + received in the current billing month |
88
+ | `emails.monthly.limit` | number | No | Plan's monthly email cap — always a number |
89
+ | `emails.monthly.sent` | number | No | Emails sent this month |
90
+ | `emails.monthly.received` | number | No | Emails received (inbound) this month |
91
+ | `emails.monthly.resets_at` | timestamp | No | When the monthly counters next reset |
92
+ | `contacts.used` | number | No | Total contacts on the account |
93
+ | `contacts.limit` | number | No | Plan's contact cap — always a number |
94
+ | `segments.used` | number | No | Segments created |
95
+ | `segments.limit` | number \| null | Yes | Plan's segment cap. `null` when the plan doesn't cap segments |
96
+ | `broadcasts.used` | number | No | Broadcasts sent |
97
+ | `broadcasts.limit` | null | Always null | Broadcasts have no plan cap — this field is always `null` |
98
+ | `ai_credits.used` | number | No | AI credits consumed in the current period |
99
+ | `ai_credits.limit` | number \| null | Yes | Plan's AI credit cap. `null` when the plan grants unlimited AI credits |
100
+ | `ai_credits.next_increase_at` | timestamp \| null | Yes | When credits are next scheduled to increase. `null` if no increase is scheduled |
101
+ | `automation_runs.used` | number | No | Automation runs in the current period |
102
+ | `automation_runs.limit` | number | No | Plan's automation run cap — always a number |
103
+ | `automation_runs.resets_at` | timestamp | No | When the automation run counter next resets |
104
+ | `domains.used` | number | No | Domains added to the account |
105
+ | `domains.limit` | number \| null | Yes | Plan's domain cap. `null` when the plan doesn't cap domains |
106
+ | `rate_limit.limit` | number | No | Max API requests allowed per `duration` window |
107
+ | `rate_limit.duration` | string | No | Length of the rate-limit window, e.g. `"1000ms"` |
108
+
109
+ ## Common Mistakes
110
+
111
+ | Mistake | Fix |
112
+ |---------|-----|
113
+ | Assuming every `limit` field can be `null` | Only `emails.daily.limit`, `segments.limit`, `ai_credits.limit`, and `domains.limit` can be `null`. `emails.monthly.limit`, `contacts.limit`, and `automation_runs.limit` are always numbers, and `broadcasts.limit` is always `null` |
114
+ | Reading `emails.daily.used` as "sent only" | `used` is `sent` + `received` combined — check `sent`/`received` separately for a breakdown |
115
+ | Expecting `ai_credits.next_increase_at` to always be set | It's `null` when no future increase is scheduled |
116
+ | Calling `.list()` or passing an ID | Usage is a single account-level snapshot — no list, get-by-id, create, update, or delete operations |
117
+ | Treating `rate_limit` as per-endpoint | It reflects the account's default API rate limit, not a per-endpoint override |
@@ -65,6 +65,7 @@ The `email.received` payload contains metadata only (sender, recipient, subject,
65
65
  |-------|---------|
66
66
  | `domain.created` / `updated` / `deleted` | Domain configuration changes |
67
67
  | `contact.created` / `updated` / `deleted` | Contact list changes (not from CSV imports) |
68
+ | `suppression.added` / `removed` | Email address added to or removed from the suppression list |
68
69
 
69
70
  ## Setup
70
71
 
@@ -144,6 +145,11 @@ The `signing_secret` is only returned once when you create the webhook. Store it
144
145
  | Get | `resend.webhooks.get(id)` | `resend.Webhooks.get(id)` |
145
146
  | Update | `resend.webhooks.update(id, params)` | `resend.Webhooks.update(params)` — `webhook_id` inside params |
146
147
  | Delete | `resend.webhooks.remove(id)` | `resend.Webhooks.remove(id)` |
148
+ | Rotate Signing Secret | `resend.webhooks.rotateSigningSecret(id)` | `resend.Webhooks.rotate_signing_secret(webhook_id)` |
149
+ | List Events | `resend.webhooks.events.list({ webhookId, ...params })` | `resend.Webhooks.list_events(webhook_id, params?)` |
150
+ | Get Event | `resend.webhooks.events.get({ webhookId, eventId })` | `resend.Webhooks.get_event(webhook_id, event_id)` |
151
+ | Replay Event | `resend.webhooks.events.replay({ webhookId, eventId })` | `resend.Webhooks.replay_event(webhook_id, event_id)` |
152
+ | List Event Attempts | `resend.webhooks.events.attempts.list({ webhookId, eventId, ...params })` | `resend.Webhooks.list_event_attempts(webhook_id, event_id, params?)` |
147
153
 
148
154
  ```typescript
149
155
  // List all webhooks
@@ -160,13 +166,64 @@ const { data: updated, error: updateError } = await resend.webhooks.update(
160
166
 
161
167
  // Delete a webhook
162
168
  const { data: deleted, error: deleteError } = await resend.webhooks.remove('4dd369bc-aa82-4ff3-97de-514ae3000ee0');
169
+
170
+ // Rotate the signing secret — for 24 hours payloads are signed with both secrets, then only the new one
171
+ const { data: rotated, error: rotateError } = await resend.webhooks.rotateSigningSecret('4dd369bc-aa82-4ff3-97de-514ae3000ee0');
172
+ // rotated: { object: 'webhook', id, signing_secret: 'whsec_...' }
173
+ // Update RESEND_WEBHOOK_SECRET with rotated.signing_secret right away
163
174
  ```
164
175
 
165
176
  **Key gotchas:**
166
- - `signing_secret` is only in the create response — `get` does not return it
177
+ - `signing_secret` is in the create, get, and rotate responses — read it back with `get`, rotate it if it leaked
167
178
  - Update can change `endpoint` and `events` — partial updates supported
168
179
  - Use `.remove()` not `.delete()` in the Node.js SDK
169
180
 
181
+ ### Delivery History (Events and Attempts)
182
+
183
+ Inspect what Resend delivered to a webhook and how the endpoint responded. Use this
184
+ to debug an endpoint that is missing events or returning errors, instead of asking
185
+ the user to check the dashboard.
186
+
187
+ ```typescript
188
+ // 1. Find the event — most recent first, forward-only pagination
189
+ const { data: events, error } = await resend.webhooks.events.list({
190
+ webhookId: '4dd369bc-aa82-4ff3-97de-514ae3000ee0',
191
+ limit: 20,
192
+ });
193
+ if (error) throw error;
194
+ // events.data[i]: { id, type, created_at, status }
195
+ // status: 'pending' | 'attempting' | 'success' | 'failed'
196
+ const eventId = events.data[0].id;
197
+
198
+ // 2. See the exact payload Resend sent, and when the next retry is due
199
+ const { data: event } = await resend.webhooks.events.get({
200
+ webhookId: '4dd369bc-aa82-4ff3-97de-514ae3000ee0',
201
+ eventId,
202
+ });
203
+ // event.next_attempt_at is null once status is 'success' or 'failed'
204
+ // event.payload is the JSON body your endpoint received
205
+
206
+ // 3. Manually replay a failed or missed event — queues one more delivery
207
+ const { data: replayed, error: replayError } = await resend.webhooks.events.replay({
208
+ webhookId: '4dd369bc-aa82-4ff3-97de-514ae3000ee0',
209
+ eventId,
210
+ });
211
+ // replayed.id is the same event ID — replay does not schedule automatic retries
212
+
213
+ // 4. See what your endpoint returned on each try
214
+ const { data: attempts } = await resend.webhooks.events.attempts.list({
215
+ webhookId: '4dd369bc-aa82-4ff3-97de-514ae3000ee0',
216
+ eventId,
217
+ });
218
+ // attempts.data[i]: { id, http_status_code, response, sent_at }
219
+ ```
220
+
221
+ Both lists take `limit` (1–100, default 20) and `after` (the last `id` of the
222
+ previous page). There is no `before` — the API rejects it with a 422.
223
+
224
+ Replay returns a 422 if the webhook is disabled, or if the event's payload is
225
+ no longer available.
226
+
170
227
  ## Signature Verification
171
228
 
172
229
  **Verify webhook signatures on every request.** Without verification, anyone can send fake webhooks to your endpoint.
@@ -273,7 +330,7 @@ If your endpoint doesn't return HTTP 200, Resend retries with exponential backof
273
330
  | 6 | 5 hours |
274
331
  | 7 | 10 hours |
275
332
 
276
- **Tip:** Always return 200 quickly, then process asynchronously if needed. You can manually replay failed webhooks from the dashboard.
333
+ **Tip:** Always return 200 quickly, then process asynchronously if needed. You can manually replay failed webhooks from the dashboard, and inspect each attempt's `http_status_code` and response body through the API — see [Delivery History](#delivery-history-events-and-attempts).
277
334
 
278
335
  ## IP Allowlist
279
336