{"_id":"@api-blitz/otel-autumn","_rev":"2-0f3185d40375603924795679a86ef698","name":"@api-blitz/otel-autumn","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@api-blitz/otel-autumn","version":"1.0.0","author":{"name":"api-blitz"},"license":"MIT","_id":"@api-blitz/otel-autumn@1.0.0","maintainers":[{"name":"ibadus","email":"ibadus@icloud.com"}],"homepage":"https://github.com/api-blitz/otel#readme","bugs":{"url":"https://github.com/api-blitz/otel/issues"},"dist":{"shasum":"241e1b616151ae3eb8b49dc3ad766508f59407b8","tarball":"https://registry.npmjs.org/@api-blitz/otel-autumn/-/otel-autumn-1.0.0.tgz","fileCount":7,"integrity":"sha512-FdN6micbVk42JPn3sNLMF8jX57DW7FTaTtpI/M4oBc/vACDSMFyUMXtLXLA5KIr21wz3rLhxumM7TmUgMr8RjA==","signatures":[{"sig":"MEUCIQCLU8drXgUZMXnEjvN4OgVlBqX4LkyxSrbNxp3FnNk3KQIgZwMmWxJq/nrJBOaMLRstYTQQ0gWDv9gimbSEwDMmyFA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":87361},"main":"./dist/index.js","type":"module","_from":"file:api-blitz-otel-autumn-1.0.0.tgz","types":"./dist/types/index.d.ts","engines":{"node":"^18.19.0 || >=20.6.0"},"exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"private":false,"scripts":{"build":"pnpm clean && tsc","clean":"rimraf dist","unit-test":"vitest --run","type-check":"tsc --noEmit","unit-test-watch":"vitest"},"_npmUser":{"name":"ibadus","email":"ibadus@icloud.com"},"_resolved":"/tmp/38837023d87b975fe92a407bcfc24d98/api-blitz-otel-autumn-1.0.0.tgz","_integrity":"sha512-FdN6micbVk42JPn3sNLMF8jX57DW7FTaTtpI/M4oBc/vACDSMFyUMXtLXLA5KIr21wz3rLhxumM7TmUgMr8RjA==","repository":{"url":"git+https://github.com/api-blitz/otel.git","type":"git"},"_npmVersion":"10.2.3","description":"OpenTelemetry instrumentation for the Autumn billing SDK","directories":{},"sideEffects":false,"_nodeVersion":"18.19.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rimraf":"3.0.2","vitest":"0.33.0","autumn-js":"^1.2.11","typescript":"^5","@types/node":"18.15.11","@opentelemetry/api":"^1.9.0","@opentelemetry/sdk-trace-base":"^2.1.0"},"peerDependencies":{"autumn-js":">=1.0.0 <2.0.0","@opentelemetry/api":">=1.9.0 <2.0.0"},"_npmOperationalInternal":{"tmp":"tmp/otel-autumn_1.0.0_1776960543600_0.7211447006439371","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@api-blitz/otel-autumn","version":"1.1.0","private":false,"publishConfig":{"access":"public"},"description":"OpenTelemetry instrumentation for the Autumn billing SDK","author":{"name":"api-blitz"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/api-blitz/otel.git"},"sideEffects":false,"type":"module","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"main":"./dist/index.js","types":"./dist/types/index.d.ts","engines":{"node":"^18.19.0 || >=20.6.0"},"dependencies":{},"devDependencies":{"@opentelemetry/api":"^1.9.0","@opentelemetry/exporter-trace-otlp-http":"^0.203.0","@opentelemetry/resources":"^2.1.0","@opentelemetry/sdk-trace-base":"^2.1.0","@opentelemetry/sdk-trace-node":"^2.1.0","@opentelemetry/semantic-conventions":"^1.37.0","@types/node":"18.15.11","autumn-js":"^1.2.11","rimraf":"3.0.2","tsx":"^4.19.2","typescript":"^5","vitest":"0.33.0"},"peerDependencies":{"@opentelemetry/api":">=1.9.0 <2.0.0","autumn-js":">=0.0.70 <2.0.0"},"scripts":{"build":"pnpm clean && tsc","clean":"rimraf dist","example":"tsx examples/demo.ts","type-check":"tsc --noEmit","unit-test":"vitest --run","unit-test-watch":"vitest"},"bugs":{"url":"https://github.com/api-blitz/otel/issues"},"homepage":"https://github.com/api-blitz/otel#readme","_id":"@api-blitz/otel-autumn@1.1.0","_integrity":"sha512-hQeL8DlGCriODIHOHSg8DAYDIrqWQbATsGVu+S8XCMBpJbEYsGxY84Ixt6q3CwikZF49rrA/bG3h8vBw8HdqQw==","_resolved":"/tmp/4b4442f3765bb1972084b9bf431baf68/api-blitz-otel-autumn-1.1.0.tgz","_from":"file:api-blitz-otel-autumn-1.1.0.tgz","_nodeVersion":"18.19.0","_npmVersion":"10.2.3","dist":{"integrity":"sha512-hQeL8DlGCriODIHOHSg8DAYDIrqWQbATsGVu+S8XCMBpJbEYsGxY84Ixt6q3CwikZF49rrA/bG3h8vBw8HdqQw==","shasum":"ccbddc33dae11544c65b87ac733ea5c28a0d4eaa","tarball":"https://registry.npmjs.org/@api-blitz/otel-autumn/-/otel-autumn-1.1.0.tgz","fileCount":7,"unpackedSize":97084,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCCH+W7eymd8WSrrOS2n1/Sg61yKTXMQG/AAfgDzf9UGQIhAJI+Xg2F9XH//4iEU/EDYwJ5UkHfuCRobYKI95/+b27l"}]},"_npmUser":{"name":"ibadus","email":"ibadus@icloud.com"},"directories":{},"maintainers":[{"name":"ibadus","email":"ibadus@icloud.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/otel-autumn_1.1.0_1777029671545_0.23851997461572516"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-23T16:09:03.493Z","modified":"2026-04-24T11:21:11.820Z","1.0.0":"2026-04-23T16:09:03.721Z","1.1.0":"2026-04-24T11:21:11.693Z"},"bugs":{"url":"https://github.com/api-blitz/otel/issues"},"author":{"name":"api-blitz"},"license":"MIT","homepage":"https://github.com/api-blitz/otel#readme","repository":{"type":"git","url":"git+https://github.com/api-blitz/otel.git"},"description":"OpenTelemetry instrumentation for the Autumn billing SDK","maintainers":[{"name":"ibadus","email":"ibadus@icloud.com"}],"readme":"# @api-blitz/otel-autumn\n\nOpenTelemetry instrumentation for the [Autumn](https://useautumn.com) billing SDK (`autumn-js`).\nCapture spans for every Autumn API call — feature access checks, usage tracking, the full billing lifecycle, customer and entity management, balances, events, plans, features, and referrals — and enrich them with rich billing metadata.\n\n## Installation\n\n```bash\nnpm install @api-blitz/otel-autumn\n# or\npnpm add @api-blitz/otel-autumn\n# or\nyarn add @api-blitz/otel-autumn\n# or\nbun add @api-blitz/otel-autumn\n```\n\n**Peer dependencies:** `@opentelemetry/api` >= 1.9.0, `autumn-js` >= 0.0.70 < 2.0.0\n\n## Quick start\n\n```ts\nimport { Autumn } from \"autumn-js\";\nimport { instrumentAutumn } from \"@api-blitz/otel-autumn\";\n\nconst autumn = new Autumn({\n  secretKey: process.env.AUTUMN_SECRET_KEY!,\n});\n\n// Instrument the client — all operations are now traced\ninstrumentAutumn(autumn);\n\n// Use the SDK normally\nawait autumn.check({ customerId: \"cus_123\", featureId: \"messages\" });\nawait autumn.billing.attach({ customerId: \"cus_123\", planId: \"pro\" });\n```\n\n`instrumentAutumn` wraps the Autumn client instance you already use — no configuration changes needed. Every SDK call creates a `CLIENT` span with operation-specific attributes, and the same client instance is returned so instrumentation is idempotent (calling it twice is a no-op).\n\n## Version compatibility\n\nWorks across `autumn-js` from the last pre-1.0 releases (`>= 0.0.70`) through the current 1.x line.\n\n- **1.x** — full 36-method coverage across `check`, `track`, and every `billing.*` / `customers.*` / `entities.*` / `balances.*` / `events.*` / `plans.*` / `features.*` / `referrals.*` sub-resource.\n- **Pre-1.0 (0.0.70 – 0.0.80)** — `check` and `track`, plus the flat top-level billing methods that existed before the 1.x rename: `attach`, `cancel`, `setupPayment`, `usage`. Pre-1.0's `Result<T, E>` response envelope is unwrapped automatically so response-side span attributes are populated the same way as on 1.x. Pre-1.0's `product_id` / `product_ids` are surfaced under the `autumn.plan_id` / `autumn.plan_ids` attribute so dashboards stay consistent across versions.\n\nMethods that don't exist on the installed SDK version are skipped silently — instrumenting a pre-1.0 client doesn't fail because `autumn.billing` / `autumn.plans` aren't present.\n\n## What gets traced\n\nThe instrumentation wraps every method on the Autumn SDK client — 2 top-level entry points plus 34 sub-resource operations across 8 namespaces.\n\n### Top-level\n\n- **`check`** — feature access checks; optionally atomic check + track via `sendEvent`\n- **`track`** — record usage events\n\n### Billing\n\n- `billing.attach` — subscribe / upgrade / downgrade a plan\n- `billing.multiAttach` — attach multiple plans in a single Stripe subscription\n- `billing.previewAttach` / `billing.previewMultiAttach` — preview charges before confirming\n- `billing.update` — update subscriptions, including `cancelAction: 'cancel_immediately' | 'cancel_end_of_cycle' | 'uncancel'`\n- `billing.previewUpdate` — preview prorated charges for an update\n- `billing.openCustomerPortal` — Stripe billing portal session\n- `billing.setupPayment` — payment-method setup session\n\n### Customers\n\n- `customers.getOrCreate`, `list`, `update`, `delete`\n\n### Entities\n\n- `entities.create`, `get`, `update`, `delete` — for per-seat / per-project scoped balances\n\n### Balances\n\n- `balances.create`, `update`, `delete`, `finalize` — manage feature balances and finalize balance locks\n\n### Events\n\n- `events.list` — list raw usage events\n- `events.aggregate` — aggregate usage over time periods\n\n### Plans\n\n- `plans.create`, `get`, `list`, `update`, `delete`\n\n### Features\n\n- `features.create`, `get`, `list`, `update`, `delete`\n\n### Referrals\n\n- `referrals.createCode`, `redeemCode`\n\n## Configuration\n\n```ts\nimport { instrumentAutumn } from \"@api-blitz/otel-autumn\";\n\ninstrumentAutumn(autumn, {\n  // Custom tracer name (default: \"@api-blitz/otel-autumn\")\n  tracerName: \"my-app-autumn-tracer\",\n\n  // Emit potentially sensitive customer data (payment URLs, portal URLs).\n  // The non-sensitive `autumn.has_payment_url` / `autumn.has_portal_url`\n  // booleans are always emitted regardless (default: false).\n  captureCustomerData: false,\n\n  // Capture plan customization blobs and checkout session params (default: false).\n  captureOptions: false,\n\n  // Master switches\n  captureResourceIds: true,\n  captureRequestAttributes: true,\n  captureResponseAttributes: true,\n\n  // Opt out of individual sub-resources\n  instrumentBilling: true,\n  instrumentCustomers: true,\n  instrumentEntities: true,\n  instrumentBalances: true,\n  instrumentEvents: true,\n  instrumentPlans: true,\n  instrumentFeatures: true,\n  instrumentReferrals: true,\n});\n```\n\n## Span attributes\n\nEvery span includes comprehensive attributes to help with debugging and monitoring.\n\n### Common attributes\n\n| Attribute            | Description                                     | Example             |\n| -------------------- | ----------------------------------------------- | ------------------- |\n| `billing.system`     | Constant `autumn`                               | `autumn`            |\n| `billing.operation`  | Resource-qualified operation name               | `billing.attach`    |\n| `autumn.resource`    | Sub-resource (or the operation for flat methods) | `billing`          |\n| `autumn.target`      | Full target (same value as `billing.operation`) | `billing.attach`    |\n| `autumn.customer_id` | Customer identifier                             | `cus_123`           |\n| `autumn.entity_id`   | Entity identifier (when provided)               | `seat_42`           |\n\n### `autumn.check`\n\n| Attribute                 | Description                                        | Example       |\n| ------------------------- | -------------------------------------------------- | ------------- |\n| `autumn.feature_id`       | Feature being checked                              | `messages`    |\n| `autumn.feature_name`     | Feature display name                               | `Messages`    |\n| `autumn.feature_type`     | `boolean` / `metered` / `credit_system`            | `metered`     |\n| `autumn.allowed`          | Whether access is allowed                          | `true`        |\n| `autumn.balance`          | Remaining balance for the feature                  | `42`          |\n| `autumn.required_balance` | Minimum balance the check required                 | `3`           |\n| `autumn.send_event`       | Whether the check also records a usage event       | `true`        |\n| `autumn.with_preview`     | Whether upsell preview was requested               | `false`       |\n| `autumn.lock`             | Balance lock id (if reserved)                      | `lock_abc`    |\n| `autumn.flag_id`          | Flag id returned by the check                      | `flag_123`    |\n| `autumn.plan_id`          | Plan id the flag originates from                   | `pro`         |\n| `autumn.has_preview`      | Whether an upsell preview was returned             | `false`       |\n| `autumn.plan_scenario`    | Denied-access scenario                             | `usage_limit` |\n\n### `autumn.track`\n\n| Attribute              | Description                                         | Example        |\n| ---------------------- | --------------------------------------------------- | -------------- |\n| `autumn.feature_id`    | Feature being tracked                               | `messages`     |\n| `autumn.event_name`    | Custom event name (when provided)                   | `message_sent` |\n| `autumn.value`         | Usage value recorded                                | `1`            |\n| `autumn.lock`          | Balance lock id (when provided)                     | `lock_abc`     |\n| `autumn.balance`       | Updated remaining balance after the track call      | `41`           |\n| `autumn.balance_count` | Number of updated balances when tracking by event   | `3`            |\n\n### `autumn.billing.*`\n\n| Attribute                         | Description                                                               | Example                 |\n| --------------------------------- | ------------------------------------------------------------------------- | ----------------------- |\n| `autumn.plan_id`                  | Plan being attached / updated                                             | `pro`                   |\n| `autumn.plan_ids`                 | Comma-joined plan ids on `multiAttach`                                    | `pro,addon_seats`       |\n| `autumn.plan_count`               | Number of plans on `multiAttach`                                          | `2`                     |\n| `autumn.plan_version`             | Target plan version                                                       | `2`                     |\n| `autumn.subscription_id`          | Target subscription (when specified)                                      | `sub_123`               |\n| `autumn.cancel_action`            | `cancel_immediately` / `cancel_end_of_cycle` / `uncancel`                 | `cancel_end_of_cycle`   |\n| `autumn.carry_over_balances`      | Carry balances into the new plan                                          | `true`                  |\n| `autumn.carry_over_usages`        | Carry usages into the new plan                                            | `true`                  |\n| `autumn.no_billing_changes`       | Skip billing-side changes for the attach/update                           | `false`                 |\n| `autumn.new_billing_subscription` | Create a new Stripe subscription instead of merging                       | `true`                  |\n| `autumn.feature_quantities_count` | Number of prepaid features configured                                     | `2`                     |\n| `autumn.discount_count`           | Number of discounts applied                                               | `1`                     |\n| `autumn.proration_behavior`       | `prorate_immediately` / `none`                                            | `prorate_immediately`   |\n| `autumn.redirect_mode`            | `always` / `if_required` / `never`                                        | `if_required`           |\n| `autumn.plan_schedule`            | `immediate` / `end_of_cycle`                                              | `immediate`             |\n| `autumn.invoice_mode`             | Invoice creation mode                                                     | `draft`                 |\n| `autumn.invoice_id`               | Stripe invoice id                                                         | `in_1N...`              |\n| `autumn.invoice_status`           | `paid` / `open` / `draft`                                                 | `paid`                  |\n| `autumn.total_amount`             | Invoice or preview total (cents)                                          | `2000`                  |\n| `autumn.currency`                 | Three-letter ISO currency                                                 | `usd`                   |\n| `autumn.has_prorations`           | Whether the preview includes prorations                                   | `true`                  |\n| `autumn.has_payment_url`          | Whether a payment URL was returned                                        | `true`                  |\n| `autumn.payment_url`              | Stripe payment URL (only when `captureCustomerData: true`)                | `https://checkout.stripe.com/...` |\n| `autumn.has_portal_url`           | Whether a portal URL was returned (`openCustomerPortal`)                  | `true`                  |\n| `autumn.portal_url`               | Billing portal URL (only when `captureCustomerData: true`)                | `https://billing.stripe.com/...` |\n| `autumn.required_action`          | `3ds_required` / `payment_method_required` / `payment_failed`             | `payment_method_required` |\n\n### `autumn.customers.*`, `autumn.entities.*`, `autumn.balances.*`\n\nCRUD operations emit the identifying keys from the request and, when present,\nfrom the response. Notable additions:\n\n- `autumn.entities.create` adds `autumn.entity_feature_id` — distinct from the\n  balance-check `autumn.feature_id`.\n- `autumn.balances.*` emits `autumn.feature_id`, `autumn.balance` (post-update\n  remaining), and `autumn.lock` on `finalize`.\n\n### `autumn.events.*`\n\n| Attribute                | Description                                                            | Example |\n| ------------------------ | ---------------------------------------------------------------------- | ------- |\n| `autumn.feature_id`      | Feature filter (when provided)                                         | `api`   |\n| `autumn.event_name`      | Event-name filter                                                      | `send`  |\n| `autumn.aggregate_range` | `aggregate` range value                                                | `7d`    |\n| `autumn.event_count`     | Events returned by `list`; summed counts across features on `aggregate` | `42`   |\n| `autumn.value`           | Summed value across all features on `aggregate`                        | `1536`  |\n| `autumn.period_count`    | Number of time buckets returned by `aggregate`                         | `7`     |\n| `autumn.feature_count`   | Number of features in the aggregate totals                             | `2`     |\n| `autumn.has_more`        | Whether `list` has more pages available                                | `false` |\n\n### `autumn.plans.*`, `autumn.features.*`\n\n| Attribute             | Description           |\n| --------------------- | --------------------- |\n| `autumn.plan_id`      | Plan identifier       |\n| `autumn.plan_name`    | Plan display name     |\n| `autumn.feature_id`   | Feature identifier    |\n| `autumn.feature_name` | Feature display name  |\n| `autumn.feature_type` | Feature type          |\n\n### `autumn.referrals.*`\n\n| Attribute                    | Description                    |\n| ---------------------------- | ------------------------------ |\n| `autumn.referral_program_id` | Referral program id            |\n| `autumn.referral_code`       | Referral code created/redeemed |\n\n## Usage examples\n\n### Feature access control\n\n```ts\nconst result = await autumn.check({\n  customerId: \"cus_123\",\n  featureId: \"messages\",\n  requiredBalance: 1,\n});\n\nif (result.allowed) {\n  console.log(`Remaining: ${result.balance?.remaining}`);\n}\n```\n\n### Atomic check + track\n\n```ts\n// Reserve 3 units and record usage in a single call\nconst result = await autumn.check({\n  customerId: \"cus_123\",\n  featureId: \"messages\",\n  requiredBalance: 3,\n  sendEvent: true,\n});\n```\n\n### Usage tracking\n\n```ts\nawait autumn.track({\n  customerId: \"cus_123\",\n  featureId: \"messages\",\n  value: 1,\n});\n```\n\n### Subscribing a customer to a plan\n\n```ts\nconst attach = await autumn.billing.attach({\n  customerId: \"cus_123\",\n  planId: \"pro\",\n});\n\nif (attach.paymentUrl) {\n  // Redirect the user to complete payment\n  console.log(`Payment URL: ${attach.paymentUrl}`);\n}\n```\n\n### Attaching multiple plans at once\n\n```ts\nawait autumn.billing.multiAttach({\n  customerId: \"cus_123\",\n  plans: [\n    { planId: \"pro\" },\n    { planId: \"addon_seats\", featureQuantities: [{ featureId: \"seats\", quantity: 5 }] },\n  ],\n});\n```\n\n### Cancelling at the end of the billing cycle\n\n```ts\nawait autumn.billing.update({\n  customerId: \"cus_123\",\n  planId: \"pro\",\n  cancelAction: \"cancel_end_of_cycle\",\n});\n```\n\n### Opening the Stripe billing portal\n\n```ts\nconst { url } = await autumn.billing.openCustomerPortal({\n  customerId: \"cus_123\",\n});\n// Redirect the user to `url`\n```\n\n### Listing and aggregating usage events\n\n```ts\n// Paginated list of raw events\nconst events = await autumn.events.list({\n  customerId: \"cus_123\",\n  featureId: \"messages\",\n});\n\n// Time-bucketed aggregate\nconst aggregate = await autumn.events.aggregate({\n  customerId: \"cus_123\",\n  featureIds: [\"messages\"],\n  range: \"7d\",\n});\n```\n\n### Managing entities (per-seat scoping)\n\n```ts\nawait autumn.entities.create({\n  customerId: \"cus_123\",\n  entityId: \"seat_42\",\n  featureId: \"seats\",\n  name: \"Seat 42\",\n});\n\n// Check a per-seat feature balance\nawait autumn.check({\n  customerId: \"cus_123\",\n  entityId: \"seat_42\",\n  featureId: \"api_calls\",\n});\n```\n\n### Error handling\n\nErrors are automatically captured in spans with full exception details and the span status is set to `ERROR`:\n\n```ts\ntry {\n  await autumn.check({ customerId: \"unknown\", featureId: \"messages\" });\n} catch (error) {\n  // The span is already marked as failed with the exception recorded\n  console.error(\"Check failed:\", error);\n}\n```\n\n## Integration with OpenTelemetry\n\nThis instrumentation integrates seamlessly with your existing OpenTelemetry setup:\n\n```ts\nimport { NodeSDK } from \"@opentelemetry/sdk-node\";\nimport { ConsoleSpanExporter } from \"@opentelemetry/sdk-trace-node\";\nimport { Resource } from \"@opentelemetry/resources\";\nimport { ATTR_SERVICE_NAME } from \"@opentelemetry/semantic-conventions\";\nimport { Autumn } from \"autumn-js\";\nimport { instrumentAutumn } from \"@api-blitz/otel-autumn\";\n\nconst sdk = new NodeSDK({\n  resource: new Resource({ [ATTR_SERVICE_NAME]: \"my-app\" }),\n  traceExporter: new ConsoleSpanExporter(),\n});\n\nsdk.start();\n\nconst autumn = new Autumn({ secretKey: process.env.AUTUMN_SECRET_KEY! });\ninstrumentAutumn(autumn);\n\n// All Autumn operations now appear in your traces\n```\n\n## Best practices\n\n1. **Instrument early** — call `instrumentAutumn()` once when initializing your Autumn client, before any API calls.\n2. **Reuse clients** — instrument a single Autumn client and reuse it throughout your app.\n3. **Context propagation** — the instrumentation automatically propagates OpenTelemetry context so Autumn spans nest correctly under parent HTTP / gRPC / DB spans.\n4. **Sensitive data** — `autumn.payment_url` and `autumn.portal_url` are gated behind `captureCustomerData: false` by default. Keep it off unless your trace pipeline is trusted and can handle payment session tokens.\n5. **Scope down sub-resources** — if your app only uses the runtime APIs (`check`, `track`, `billing.*`), disable admin sub-resources (`instrumentPlans: false`, `instrumentFeatures: false`) to keep the instrumentation surface minimal.\n\n## Framework integration\n\n### Express\n\n```ts\nimport express from \"express\";\nimport { Autumn } from \"autumn-js\";\nimport { instrumentAutumn } from \"@api-blitz/otel-autumn\";\n\nconst app = express();\nconst autumn = new Autumn({ secretKey: process.env.AUTUMN_SECRET_KEY! });\ninstrumentAutumn(autumn);\n\napp.post(\"/messages\", async (req, res) => {\n  const allowed = await autumn.check({\n    customerId: req.auth.userId,\n    featureId: \"messages\",\n  });\n  if (!allowed.allowed) return res.status(402).send(\"Quota exceeded\");\n\n  // ... send the message ...\n\n  await autumn.track({\n    customerId: req.auth.userId,\n    featureId: \"messages\",\n    value: 1,\n  });\n  res.json({ ok: true });\n});\n```\n\n### Next.js\n\n```ts\n// lib/autumn.ts\nimport { Autumn } from \"autumn-js\";\nimport { instrumentAutumn } from \"@api-blitz/otel-autumn\";\n\nconst autumn = new Autumn({ secretKey: process.env.AUTUMN_SECRET_KEY! });\ninstrumentAutumn(autumn);\n\nexport { autumn };\n```\n\n```ts\n// app/api/messages/route.ts\nimport { autumn } from \"@/lib/autumn\";\n\nexport async function POST() {\n  const allowed = await autumn.check({\n    customerId: \"cus_123\",\n    featureId: \"messages\",\n  });\n  if (!allowed.allowed) return new Response(\"Quota exceeded\", { status: 402 });\n\n  await autumn.track({\n    customerId: \"cus_123\",\n    featureId: \"messages\",\n    value: 1,\n  });\n  return Response.json({ ok: true });\n}\n```\n\n### Hono\n\n```ts\nimport { Hono } from \"hono\";\nimport { Autumn } from \"autumn-js\";\nimport { instrumentAutumn } from \"@api-blitz/otel-autumn\";\n\nconst app = new Hono();\nconst autumn = new Autumn({ secretKey: process.env.AUTUMN_SECRET_KEY! });\ninstrumentAutumn(autumn);\n\napp.post(\"/messages\", async (c) => {\n  const allowed = await autumn.check({\n    customerId: \"cus_123\",\n    featureId: \"messages\",\n  });\n  if (!allowed.allowed) return c.json({ error: \"Quota exceeded\" }, 402);\n\n  await autumn.track({ customerId: \"cus_123\", featureId: \"messages\", value: 1 });\n  return c.json({ ok: true });\n});\n```\n\n## TypeScript support\n\nThis package includes full TypeScript definitions. The instrumentation preserves the full type surface of the `Autumn` SDK:\n\n```ts\nimport { Autumn } from \"autumn-js\";\nimport { instrumentAutumn } from \"@api-blitz/otel-autumn\";\n\nconst autumn = new Autumn({ secretKey: \"...\" });\ninstrumentAutumn(autumn);\n\n// Full type safety is preserved\nconst result = await autumn.billing.attach({\n  customerId: \"cus_123\",\n  planId: \"pro\",\n  cancelAction: \"cancel_end_of_cycle\", // TypeScript knows valid values\n});\n\n// TypeScript error: Property 'invalidMethod' does not exist\n// autumn.billing.invalidMethod();\n```\n\nAll semantic-attribute constants are exported for building custom queries and\ndashboards:\n\n```ts\nimport {\n  SEMATTRS_AUTUMN_CUSTOMER_ID,\n  SEMATTRS_AUTUMN_PLAN_ID,\n  SEMATTRS_AUTUMN_ALLOWED,\n  SEMATTRS_BILLING_OPERATION,\n} from \"@api-blitz/otel-autumn\";\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}