vybekiit 0.7.26 → 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.
- package/dist/bin.js +3891 -1301
- package/dist/global-skills/aws-cdk/SKILL.md +19 -5
- package/dist/global-skills/aws-cdk/references/fast-deployments.md +191 -0
- package/dist/global-skills/aws-cdk/references/troubleshooting-deployment.md +16 -0
- package/dist/global-skills/aws-cloudformation/SKILL.md +16 -26
- package/dist/global-skills/aws-cloudformation/references/check-cloudformation-template-compliance.script.md +7 -3
- package/dist/global-skills/aws-cloudformation/references/cloudformation-language-server.md +177 -0
- package/dist/global-skills/aws-cloudformation/references/cloudformation-pre-deploy-validation.script.md +8 -2
- package/dist/global-skills/aws-cloudformation/references/persist-template-context.script.md +5 -8
- package/dist/global-skills/aws-cloudformation/references/retrieve-template-context.script.md +1 -1
- package/dist/global-skills/aws-cloudformation/references/security-considerations.md +51 -0
- package/dist/global-skills/aws-cloudformation/references/troubleshoot-failed-stack.script.md +138 -0
- package/dist/global-skills/aws-cloudformation/references/{validate-cloudformation-template.script.md → validate-with-cfn-lint.script.md} +15 -27
- package/dist/global-skills/aws-cloudformation/references/validate-with-cloudformation-validate.script.md +181 -0
- package/dist/global-skills/aws-cloudformation/references/validation-tool-selection.md +44 -0
- package/dist/global-skills/aws-serverless/SKILL.md +9 -1
- package/dist/global-skills/aws-serverless/references/architecture.md +3 -1
- package/dist/global-skills/aws-serverless/references/lambda.md +3 -1
- package/dist/global-skills/aws-serverless/references/orchestration.md +1 -0
- package/dist/global-skills/better-auth-best-practices/SKILL.md +18 -8
- package/dist/global-skills/eas-app-stores/SKILL.md +31 -15
- package/dist/global-skills/eas-app-stores/agents/openai.yaml +2 -2
- package/dist/global-skills/eas-app-stores/references/ios-app-store.md +37 -32
- package/dist/global-skills/eas-app-stores/references/native-ios.md +167 -0
- package/dist/global-skills/eas-app-stores/references/play-store.md +3 -7
- package/dist/global-skills/eas-app-stores/references/testflight.md +39 -35
- package/dist/global-skills/eas-simulator/SKILL.md +48 -26
- package/dist/global-skills/eas-simulator/references/controllers.md +32 -3
- package/dist/global-skills/eas-simulator/references/run-your-app.md +34 -4
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -4
- package/dist/global-skills/eas-update/SKILL.md +146 -0
- package/dist/global-skills/eas-update/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-animation/RECIPES.md +2 -2
- package/dist/global-skills/expo-animation/SKILL.md +9 -2
- package/dist/global-skills/expo-brownfield/SKILL.md +18 -11
- package/dist/global-skills/expo-brownfield/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-brownfield/references/brownfield-integrated.md +94 -69
- package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +40 -42
- package/dist/global-skills/expo-brownfield/references/comparison.md +5 -5
- package/dist/global-skills/expo-brownfield/references/feature-integration.md +163 -0
- package/dist/global-skills/expo-brownfield/references/troubleshooting.md +17 -17
- package/dist/global-skills/expo-brownfield/references/version-compatibility.md +40 -0
- package/dist/global-skills/expo-data-fetching/SKILL.md +27 -6
- package/dist/global-skills/expo-design-system/SKILL.md +27 -7
- package/dist/global-skills/expo-design-system/references/audit.md +7 -2
- package/dist/global-skills/expo-design-system/references/native-slop.md +74 -0
- package/dist/global-skills/expo-examples/SKILL.md +0 -1
- package/dist/global-skills/expo-examples/references/catalog.md +1 -1
- package/dist/global-skills/expo-migrate-module/SKILL.md +21 -10
- package/dist/global-skills/expo-migrate-module/references/compatibility.md +80 -23
- package/dist/global-skills/expo-migrate-module/references/migration-map.md +162 -11
- package/dist/global-skills/expo-native-ui/SKILL.md +25 -16
- package/dist/global-skills/expo-native-ui/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-native-ui/references/controls.md +5 -46
- package/dist/global-skills/expo-native-ui/references/icons.md +21 -2
- package/dist/global-skills/expo-native-ui/references/media.md +15 -20
- package/dist/global-skills/expo-native-ui/references/visual-effects.md +12 -11
- package/dist/global-skills/expo-overview/SKILL.md +17 -12
- package/dist/global-skills/expo-router/SKILL.md +5 -3
- package/dist/global-skills/expo-router/references/tabs.md +5 -5
- package/dist/global-skills/expo-upgrade/SKILL.md +3 -1
- package/dist/global-skills/expo-web-to-native/references/false-friends.md +2 -2
- package/dist/global-skills/expo-web-to-native/references/native-patterns.md +1 -1
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +13 -16
- package/dist/global-skills/firebase-ai-logic-basics/references/ios_setup.md +4 -5
- package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_android.md +4 -4
- package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_web.md +3 -3
- package/dist/global-skills/firebase-auth-basics/SKILL.md +11 -6
- package/dist/global-skills/firebase-auth-basics/references/client_sdk_android.md +4 -5
- package/dist/global-skills/firebase-auth-basics/references/client_sdk_web.md +3 -3
- package/dist/global-skills/firebase-auth-basics/references/flutter_setup.md +24 -25
- package/dist/global-skills/firebase-auth-basics/references/security_rules.md +4 -2
- package/dist/global-skills/firebase-crashlytics/references/android_setup.md +7 -4
- package/dist/global-skills/firebase-crashlytics/references/ios_setup.md +2 -3
- package/dist/global-skills/firebase-data-connect/SKILL.md +2 -1
- package/dist/global-skills/firebase-data-connect/examples.md +4 -4
- package/dist/global-skills/firebase-data-connect/reference/config.md +5 -4
- package/dist/global-skills/firebase-data-connect/reference/realtime.md +1 -2
- package/dist/global-skills/firebase-data-connect/reference/sdk_flutter.md +2 -2
- package/dist/global-skills/firebase-data-connect/reference/sdk_ios.md +2 -2
- package/dist/global-skills/firebase-data-connect/reference/sdk_web.md +17 -6
- package/dist/global-skills/firebase-data-connect/reference/security.md +5 -5
- package/dist/global-skills/firebase-data-connect/templates.md +2 -1
- package/dist/global-skills/firebase-firestore/SKILL.md +20 -8
- package/dist/global-skills/firebase-firestore/references/enterprise/android_sdk_usage.md +5 -4
- package/dist/global-skills/firebase-firestore/references/enterprise/data_model.md +12 -3
- package/dist/global-skills/firebase-firestore/references/enterprise/indexes.md +16 -18
- package/dist/global-skills/firebase-firestore/references/enterprise/provisioning.md +1 -1
- package/dist/global-skills/firebase-firestore/references/enterprise/python_sdk_usage.md +5 -1
- package/dist/global-skills/firebase-firestore/references/enterprise/web_sdk_usage.md +7 -7
- package/dist/global-skills/firebase-firestore/references/standard/android_sdk_usage.md +5 -5
- package/dist/global-skills/firebase-firestore/references/standard/flutter_setup.md +4 -4
- package/dist/global-skills/firebase-firestore/references/standard/indexes.md +16 -18
- package/dist/global-skills/firebase-firestore/references/standard/provisioning.md +1 -1
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +0 -5
- package/dist/global-skills/firebase-remote-config-basics/references/android_setup.md +36 -8
- package/dist/global-skills/firebase-remote-config-basics/references/ios_setup.md +1 -7
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +17 -6
- package/dist/global-skills/{firebase-firestore/references/standard/security_rules.md → firestore-rules-creation/SKILL.md} +24 -13
- package/dist/global-skills/grow-my-customers/SKILL.md +23 -0
- package/dist/global-skills/instrument-feature-flags/SKILL.md +25 -25
- package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +141 -285
- package/dist/global-skills/instrument-feature-flags/references/android.md +6 -15
- package/dist/global-skills/instrument-feature-flags/references/api.md +4 -11
- package/dist/global-skills/instrument-feature-flags/references/best-practices.md +1 -13
- package/dist/global-skills/instrument-feature-flags/references/django.md +14 -27
- package/dist/global-skills/instrument-feature-flags/references/dotnet.md +20 -79
- package/dist/global-skills/instrument-feature-flags/references/elixir.md +1 -9
- package/dist/global-skills/instrument-feature-flags/references/flask.md +13 -13
- package/dist/global-skills/instrument-feature-flags/references/flutter.md +3 -24
- package/dist/global-skills/instrument-feature-flags/references/go.md +3 -15
- package/dist/global-skills/instrument-feature-flags/references/ios.md +4 -17
- package/dist/global-skills/instrument-feature-flags/references/java.md +5 -13
- package/dist/global-skills/instrument-feature-flags/references/laravel.md +13 -17
- package/dist/global-skills/instrument-feature-flags/references/next-js.md +25 -32
- package/dist/global-skills/instrument-feature-flags/references/nodejs.md +8 -15
- package/dist/global-skills/instrument-feature-flags/references/php.md +1 -15
- package/dist/global-skills/instrument-feature-flags/references/python.md +2 -15
- package/dist/global-skills/instrument-feature-flags/references/react-native.md +13 -15
- package/dist/global-skills/instrument-feature-flags/references/react.md +17 -21
- package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +37 -83
- package/dist/global-skills/instrument-feature-flags/references/ruby.md +2 -15
- package/dist/global-skills/instrument-feature-flags/references/rust.md +13 -25
- package/dist/global-skills/instrument-feature-flags/references/usage.md +14 -63
- package/dist/global-skills/instrument-feature-flags/references/web.md +9 -14
- package/dist/global-skills/instrument-product-analytics/SKILL.md +29 -29
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-static.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-view-transitions.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/android.md +72 -107
- package/dist/global-skills/instrument-product-analytics/references/angular.md +26 -28
- package/dist/global-skills/instrument-product-analytics/references/astro.md +13 -24
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +45 -63
- package/dist/global-skills/instrument-product-analytics/references/django.md +14 -27
- package/dist/global-skills/instrument-product-analytics/references/dotnet.md +20 -79
- package/dist/global-skills/instrument-product-analytics/references/elixir.md +47 -49
- package/dist/global-skills/instrument-product-analytics/references/flask.md +13 -13
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +60 -90
- package/dist/global-skills/instrument-product-analytics/references/go.md +17 -56
- package/dist/global-skills/instrument-product-analytics/references/identify-users.md +15 -15
- package/dist/global-skills/instrument-product-analytics/references/ios.md +11 -15
- package/dist/global-skills/instrument-product-analytics/references/laravel.md +13 -17
- package/dist/global-skills/instrument-product-analytics/references/next-js.md +25 -32
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +13 -27
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +14 -28
- package/dist/global-skills/instrument-product-analytics/references/php.md +33 -84
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +229 -9
- package/dist/global-skills/instrument-product-analytics/references/python.md +415 -106
- package/dist/global-skills/instrument-product-analytics/references/react-native.md +161 -155
- package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +12 -33
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +15 -33
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +12 -33
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +26 -41
- package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +37 -83
- package/dist/global-skills/instrument-product-analytics/references/ruby.md +48 -108
- package/dist/global-skills/instrument-product-analytics/references/svelte.md +18 -24
- package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +17 -19
- package/dist/global-skills/instrument-product-analytics/references/usage.md +14 -63
- package/dist/global-skills/instrument-product-analytics/references/vue-js.md +29 -28
- package/dist/global-skills/manifest.json +8 -2
- package/dist/global-skills/mongodb-search-and-ai/SKILL.md +28 -37
- package/dist/global-skills/mongodb-search-and-ai/references/automated-embedding.md +438 -0
- package/dist/global-skills/mongodb-search-and-ai/references/hybrid-search.md +60 -4
- package/dist/global-skills/mongodb-search-and-ai/references/vector-search.md +46 -108
- package/dist/global-skills/neon/SKILL.md +207 -213
- package/dist/global-skills/neon/references/auth.md +12 -0
- package/dist/global-skills/neon/references/claimable-neon.md +10 -14
- package/dist/global-skills/neon/references/function-triggers.md +53 -0
- package/dist/global-skills/neon/references/logs-loki.md +61 -0
- package/dist/global-skills/neon/references/parse-env.md +32 -0
- package/dist/global-skills/neon/references/sdk.md +7 -0
- package/dist/global-skills/neon-ai-gateway/SKILL.md +14 -16
- package/dist/global-skills/neon-auth/SKILL.md +155 -0
- package/dist/global-skills/neon-auth/references/managed-auth.md +173 -0
- package/dist/global-skills/neon-auth/references/self-managed.md +25 -0
- package/dist/global-skills/neon-functions/SKILL.md +159 -84
- package/dist/global-skills/neon-functions/references/ai-sdk.md +4 -6
- package/dist/global-skills/neon-functions/references/function-triggers.md +249 -0
- package/dist/global-skills/neon-functions/references/mastra-studio.md +3 -3
- package/dist/global-skills/neon-functions/references/mcp.md +1 -1
- package/dist/global-skills/neon-functions/references/production-hardening.md +340 -0
- package/dist/global-skills/neon-functions/references/sse.md +8 -5
- package/dist/global-skills/neon-object-storage/SKILL.md +10 -11
- package/dist/global-skills/neon-postgres/SKILL.md +120 -17
- package/dist/global-skills/neon-postgres/references/full-text-search.md +99 -0
- package/dist/global-skills/neon-postgres/references/hybrid-search.md +90 -0
- package/dist/global-skills/neon-postgres/references/lakebase-search-drizzle.md +172 -0
- package/dist/global-skills/neon-postgres/references/vector-search.md +137 -0
- package/dist/global-skills/neon-postgres-branches/SKILL.md +3 -3
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +1 -1
- package/dist/global-skills/onboarding/SKILL.md +8 -6
- package/dist/global-skills/resend/SKILL.md +4 -2
- package/dist/global-skills/resend/references/broadcasts.md +6 -1
- package/dist/global-skills/resend/references/receiving.md +29 -10
- package/dist/global-skills/resend/references/sending/email-management.md +14 -4
- package/dist/global-skills/resend/references/topics.md +9 -6
- package/dist/global-skills/resend/references/usage.md +117 -0
- package/dist/global-skills/resend/references/webhooks.md +59 -2
- package/dist/global-skills/stripe-best-practices/SKILL.md +35 -29
- package/dist/global-skills/stripe-best-practices/references/billing.md +9 -2
- package/dist/global-skills/stripe-best-practices/references/payments.md +4 -2
- package/dist/global-skills/stripe-best-practices/references/security.md +3 -1
- package/dist/global-skills/stripe-best-practices/references/tax.md +39 -20
- package/dist/global-skills/supabase/SKILL.md +6 -0
- package/dist/global-skills/use-railway/SKILL.md +42 -22
- package/dist/global-skills/use-railway/references/analyze-db.md +7 -6
- package/dist/global-skills/use-railway/references/cloud-agents.md +70 -0
- package/dist/global-skills/use-railway/references/configure.md +17 -2
- package/dist/global-skills/use-railway/references/databases.md +107 -0
- package/dist/global-skills/use-railway/references/deploy.md +5 -5
- package/dist/global-skills/use-railway/references/feature-flags.md +25 -13
- package/dist/global-skills/use-railway/references/iac.md +66 -77
- package/dist/global-skills/use-railway/references/operate.md +26 -3
- package/dist/global-skills/use-railway/references/request.md +31 -23
- package/dist/global-skills/use-railway/references/setup.md +16 -5
- package/dist/global-skills/use-railway/references/tracing.md +261 -0
- package/dist/global-skills/use-railway/references/usage.md +52 -0
- package/dist/global-skills/validate-my-idea/SKILL.md +54 -0
- package/dist/global-skills/{feedback → vybekiit-feedback}/SKILL.md +16 -12
- package/dist/global-skills/watch-my-app/SKILL.md +53 -0
- package/dist/global-skills/workers-best-practices/SKILL.md +36 -103
- package/dist/global-skills/workers-best-practices/references/configuration.md +139 -0
- package/dist/global-skills/workers-best-practices/references/platform-apis.md +51 -0
- package/dist/global-skills/workers-best-practices/references/{rules.md → runtime-patterns.md} +13 -137
- package/dist/global-skills/wrangler/SKILL.md +48 -901
- package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Sources/main.swift +19 -15
- package/package.json +9 -8
- package/dist/global-skills/expo-native-ui/references/animations.md +0 -220
- package/dist/global-skills/firebase-firestore/references/enterprise/security_rules.md +0 -577
- 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
|
-
|
|
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://
|
|
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://
|
|
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
|
-
|
|
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.
|
|
31
|
-
|
|
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.
|
|
46
|
-
|
|
47
|
-
start exactly one preview with the agent's
|
|
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
|
|
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.
|
|
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
|
-
|
|
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 } =
|
|
222
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|